一、單例的由來
在我們的程序中,如果需要多個線程操作同一對象,需要保證對象的唯一性。如何保證唯一性呢?
二、解決的問題
對象實例化過程中,只實例化一次
三、解決的思路
有一個實例化過程(僅僅只有一次),提供返回實例的方法
四、單例模式的分類
我們從幾個方面考慮單例模型的性能:安全性、
1、餓漢式
public class HungrySingleton {
// 加載的時候產生實例對象
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {}
// 返回實例對象
public static HungrySingleton getInstance() {
return instance;
}
}
輸出結果:
安全性:加載的時候已經被實例化,所以只有這一次,線程安全的。
懶加載:沒有延遲加載。
性能:比較好
2、懶漢式
public class HoomSingleton {
private static HoomSingleton instance = null;
rivate HoomSingleton() {}
public static HoomSingleton getInstance() {
if (null == instance) {
instance = new HoomSingleton();
}
return instance;
}
}
線程安全:不能保證實例對象的唯一性
3、懶漢式+同步方法
public class HoomSynSingleton {
private static HoomSynSingleton instance = null;
private HoomSynSingleton() {}
public synchronized static HoomSynSingleton getInstance() {
if (null == instance) {
instance = new HoomSynSingleton();
}
return instance;
}
}
性能安全:安全
懶加載
性能:synchronized退化到了串行執行
4、DCL併發模式
// double-check-locking
public class DCL {
private static DCL instance = null;
private DCL() {}
public static DCL getInstance() {
if (null == instance) {
synchronized (DCL.class) {
if (null == instance)
instance = new DCL();
}
}
return instance;
}
線程安全
懶加載
性能比較好
5、Holder
聲明類的時候,成員變量中不聲明實例變量,而放到內部靜態類中。
一種廣泛使用的一個單例方式。
public class HolderDemo {
private HolderDemo() {}
private static class Holder {
private static HolderDemo instance = new HolderDemo();
}
// 懶加載
// synchronized
public static HolderDemo getInstance() {
return Holder.instance;
}
}