定義
保證一個類僅有一個實(shí)例衣屏,并提供一個訪問它的全局訪問點(diǎn)。
單例的使用場景
在一個系統(tǒng)中辩棒,要求一個類有且僅有一個對象狼忱,具體使用場景如下:
- 整個項(xiàng)目需要一個共享訪問點(diǎn)或共享數(shù)據(jù)。
- 創(chuàng)建一個對象需要耗費(fèi)的資源過多一睁,比如訪問 I/O或者數(shù)據(jù)庫等資源钻弄。
- 工具類對象。
單例模式的6六種寫法
1. 餓漢模式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance(){
return instance;
}
}
優(yōu)點(diǎn):
- 這種方式在類加載時就完成初始化了者吁,獲取對象但速度快窘俺。
- 避免多線程但同步問題。
缺點(diǎn):
- 類加載較慢复凳。
- 沒有達(dá)到懶加載的效果瘤泪,如果從始至終都未使用果這個實(shí)例,這會造成內(nèi)存的浪費(fèi)育八。
2. 懶漢模式(線程不安全)
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
優(yōu)點(diǎn):
- 節(jié)省資源
缺點(diǎn):
- 第一次實(shí)例化對象時較慢对途。
- 多線程時不能正常工作。
3. 懶漢模式(線程安全)
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
優(yōu)點(diǎn):
- 多線程中很好的工作髓棋。
缺點(diǎn):
- 每次調(diào)用
getInstance
方法時都需要同步实檀,這會造成不必要的同步開銷。
大部分時候我們是用不到同步的按声,所以膳犹,不建議用這種模式。
4. 雙重檢查模式
public class Singleton {
private volatile static Singleton instance;
private Singleton() {
}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
優(yōu)點(diǎn):
- 資源利用率高儒喊。
- 避免多余同步镣奋。
- 線程安全。
缺點(diǎn):
- 使用了
volatile
或多或少會影響性能怀愧。 - 第一次實(shí)例化對象時較慢侨颈。
- 在高并發(fā)某些情況下會出現(xiàn)失效問題。
DCL
(Double Check Lock) 在高并發(fā)環(huán)境下也會有一定的缺陷芯义,DCL
雖然在一定程度上解決了資源的消耗哈垢、多余的同步、線程安全問題等問題扛拨,但還是在某些情況會出現(xiàn)失效的問題耘分,也就是DCL
失效。這里建議用靜態(tài)內(nèi)部類單例模式來代替DCL
。
5. 靜態(tài)內(nèi)部類單例模式 (推薦使用)
public class Singleton {
private Singleton() {
}
public static Singleton getInstance(){
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
}
第一次加載
Singleton
類時并不會初始化sInstance
求泰。 只有在第一次調(diào)用getInstance
方法時虛擬機(jī)才會加載SingletonHolder
并初始化 sInstance央渣。
優(yōu)點(diǎn):
- 資源利用率高。
- 避免多余同步渴频。
- 線程安全芽丹。
缺點(diǎn):
- 暫無
6. 枚舉單例
public enum Singleton {
INSTANCE;
public void doSomeThing() {
}
}
優(yōu)點(diǎn):
- 任何情況下都是單例。
- 默認(rèn)線程安全卜朗。
缺點(diǎn):
- 簡單
- 可讀性不高拔第。
總結(jié):到這里6種單例寫法已介紹完,至于選擇那種形勢的單例模式场钉,取決與你項(xiàng)目本身情況:是否復(fù)雜的高并發(fā)環(huán)境蚊俺,或者是否需要控制單例對象的資源消耗。