模式定義:
確保某一個類只有一個實例,並且提供一個全局訪問點
模式結構:
略
模式實現:
這裏介紹三種實現方式,分別是DCL(雙重檢查鎖定),靜態內部類,枚舉。
DCL:
public class Singleton {
//通過volatile關鍵字來確保安全
private volatile static Singleton singleton;
private Singleton() {
}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
必須加volatile,否則可能會出現問題:singleton只是一個地址,而沒有創建對象。
靜態內部類:
class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton() {
}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
這種方式是Singleton類被裝載了,instance不一定被初始化。因爲SingletonHolder類沒有被主動使用,只有顯示通過調用getInstance方法時,纔會顯示裝載SingletonHolder類,從而實例化instance。
枚舉:
class Resource {
}
public enum SomeThing {
INSTANCE;
private Resource instance;
SomeThing() {
instance = new Resource();
}
public Resource getInstance() {
return instance;
}
}
它不僅能避免多線程同步問題,而且還能防止反序列化重新創建新的對象,可謂是很堅強的壁壘啊,不過,個人認爲由於1.5中才加入enum特性,用這種方式寫不免讓人感覺生疏,在實際工作中,我也很少看見有人這麼寫過。
模式優點:
1、節約了系統資源。由於系統中只存在一個實例對象,對與一些需要頻繁創建和銷燬對象的系統而言,單例模式無疑節約了系統資源和提高了系統的性能
2、因爲單例類封裝了它的唯一實例,所以它可以嚴格控制客戶怎樣以及何時訪問它。
模式缺點:
1、由於單例模式中沒有抽象層,因此單例類的擴展有很大的困難。
2、單例類的職責過重,在一定程度上違背了“單一職責原則”
適用場景:
1、系統只需要一個實例對象,如系統要求提供一個唯一的序列號生成器,或者需要考慮資源消耗太大而只允許創建一個對象。
2、客戶調用類的單個實例只允許使用一個公共訪問點,除了該公共訪問點,不能通過其他途徑訪問該實例。
資料:
http://cmsblogs.com/?p=2161
http://blog.csdn.net/yy254117440/article/details/52305175