使用場景
只需要單個實例,比如說線程池捉蚤、緩存等抬驴,如果存在兩個不同的實例,就會引發(fā)種種問題缆巧。單例模式的設計就是為了保持永遠只有一個實例布持。但是由于性能、存儲上的考慮陕悬,單例模式有以下幾種實現(xiàn)方式题暖,可根據(jù)應用場景自行選擇。
demo1 普通模式
public class Singleton {
private static SingleTon uniqueInstance;
private static Singleton getInstance() {
uniqueInstance = new Singleton();
}
}
demo2 延遲實例化模式
public class Singleton {
private static SingleTon uniqueInstance;
//添加synchronized防止兩個線程同時進入到該方法
//避免實例化過程進行兩次
private synchronized static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
demo3 急切實例化模式
public class Singleton {
//保證線程安全捉超,但是JVM在加載這個類時會馬上創(chuàng)建實例
//對性能會產(chǎn)生影響
private static SingleTon uniqueInstance = new Singleton();
private static Singleton getInstance() {
return uniqueInstance;
}
}
demo4 雙重檢查加鎖
public class Singleton {
//volatile確保變量被初始化后胧卤,多個線程能正確的處理該變量
private volatile static SingleTon uniqueInstance;
private static Singleton getInstance() {
if (uniqueInstance == null) {
//避免單例被初始化兩次
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
關鍵點
- 私有的構(gòu)造器
- 一個靜態(tài)方法和一個靜態(tài)變量
需要注意的點
- 在性能和資源的限制下選擇最合適的方案
特定環(huán)境下的問題
- Java1.2之前, 單例沒有全局引用時會被垃圾回收器回收, 1.2之后已經(jīng)修復.
- 每個類加載器都定義了一個命名空間, 如果有多個類加載器, 就有可能會將一個類加載多次, 產(chǎn)生多個單例并存的情況. 解決辦法: 自行指定類加載器, 并指定同一個類加載器.