單例模式的適用場(chǎng)景:各種管理類、各種工廠類
實(shí)現(xiàn)方式:
餓漢式:
優(yōu)點(diǎn):簡(jiǎn)潔,易懂,個(gè)人更傾向?qū)嶋H中使用這種
缺點(diǎn):每次類加載時(shí)就會(huì)實(shí)例化 ,不能防止反序列化
package com.example.demo;
public class Singleton1 {
private static final Singleton1 INSTANCE = new Singleton1();
private Singleton1(){
}
public static Singleton1 getInstance(){
return INSTANCE;
}
public static void main(String[] args) {
for(int i=0; i<100; i++) {
new Thread(()->{
System.out.println(Singleton1.getInstance().hashCode());
}).start();
}
}
}
懶漢式
缺點(diǎn):加鎖效率低
package com.example.demo;
public class Singleton2 {
private static volatile Singleton2 INSTANCE;
private Singleton2(){
}
public static Singleton2 getInstance(){
//雙重檢查,第一層是為了如果已經(jīng)實(shí)例化其他線程沒必要走到加鎖那一步
if(INSTANCE == null) {
synchronized (Singleton2.class) {
if(INSTANCE == null) {
INSTANCE = new Singleton2();
}
}
}
return INSTANCE;
}
public static void main(String[] args) {
for(int i=0; i<100; i++) {
new Thread(()->{
System.out.println(Singleton2.getInstance().hashCode());
}).start();
}
}
}
靜態(tài)內(nèi)部類實(shí)現(xiàn)
缺點(diǎn):可以被反序列化
package com.example.demo;
public class Singleton3 {
private Singleton3(){
}
private static class Singleton3Holder{
private final static Singleton3 INSTANCE = new Singleton3();
}
public static Singleton3 getInstance(){
return Singleton3Holder.INSTANCE;
}
public static void main(String[] args) {
for(int i=0; i<100; i++) {
new Thread(()->{
System.out.println(Singleton3.getInstance().hashCode());
}).start();
}
}
}
枚舉方式實(shí)現(xiàn)
解決了線程問題和反序列化問題,傳說中最完美方式
package com.example.demo;
public enum Singleton4 {
INSTANCE;
public static void main(String[] args) {
for(int i=0; i<100; i++) {
new Thread(()->{
System.out.println(Singleton4.INSTANCE.hashCode());
}).start();
}
}
}