要求:構(gòu)造函數(shù)設(shè)置為private、通過靜態(tài)方法或枚舉返回單例對象
確保單例對象有且只有一個(尤其是多線程環(huán)境)、且反序列化時不會重新構(gòu)建對象
步驟:構(gòu)造函數(shù)私有化->暴露公共靜態(tài)方法->確保線程安全
餓漢模式
class Singleton {
// 構(gòu)造函數(shù)私有化
private Singleton() {}
// 共有靜態(tài)方法、暴露獲取單例對象接口
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
懶漢模式
優(yōu)點:單例只有在使用時才會被實例化
缺點:第一次加載時反應(yīng)稍慢;每次調(diào)用getInstance都進行同步,造成不必要的同步開銷
class Singleton {
private static Singleton instance;
// 構(gòu)造函數(shù)私有化
private Singleton() {}
//添加了synchronized關(guān)鍵字,保證多線程單例對象唯一
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Double Check Lock(DCL)模式
優(yōu)點:解決了懶漢模式的大部分缺點、資源利用率高
缺點:第一次加載時反應(yīng)稍慢
class Singleton3 {
private volatile static Singleton instance = null;
// 構(gòu)造函數(shù)私有化
private Singleton() {}
public static Singleton getInstance() {
//第一次判空:避免不必要的同步
if (instance == null) {
synchronized (Singleton.class) {
//第二次判空:創(chuàng)建實例
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
靜態(tài)內(nèi)部類模式
優(yōu)點:確保線程安全、保證單例、延遲了單例的實例化
class Singleton {
// 構(gòu)造函數(shù)私有化
private Singleton() {}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
// 靜態(tài)內(nèi)部類
private static class SingletonHolder{
private static final Singleton instance = new Singleton();
}
}
以上單例方法在反序列化情況需加入以下方法
private Object readResolve() throws ObjectStreamException {
//反序列化直接返回對象,而不是生成新對象
return instance;
}
因為序列化可以將一個單例的實例對象寫入磁盤,然后再讀出來,從而有效的獲取一個實例,
即使構(gòu)造函數(shù)私有,反序列化依舊可以通過特殊途徑獲得新的實例
枚舉單例
線程安全且單例,反序列化情況也不會生成新的實例
public enum Singleton {
INSTANCE;
}
個人博客 請戳:http://lutils.cn