要求:構(gòu)造函數(shù)設(shè)置為private、通過(guò)靜態(tài)方法或枚舉返回單例對(duì)象
確保單例對(duì)象有且只有一個(gè)(尤其是多線程環(huán)境)娶视、且反序列化時(shí)不會(huì)重新構(gòu)建對(duì)象
步驟:構(gòu)造函數(shù)私有化->暴露公共靜態(tài)方法->確保線程安全
餓漢模式
class Singleton {
// 構(gòu)造函數(shù)私有化
private Singleton() {}
// 共有靜態(tài)方法琴拧、暴露獲取單例對(duì)象接口
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
懶漢模式
優(yōu)點(diǎn):單例只有在使用時(shí)才會(huì)被實(shí)例化
缺點(diǎn):第一次加載時(shí)反應(yīng)稍慢;每次調(diào)用getInstance都進(jìn)行同步,造成不必要的同步開(kāi)銷
class Singleton {
private static Singleton instance;
// 構(gòu)造函數(shù)私有化
private Singleton() {}
//添加了synchronized關(guān)鍵字,保證多線程單例對(duì)象唯一
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Double Check Lock(DCL)模式
優(yōu)點(diǎn):解決了懶漢模式的大部分缺點(diǎn)忽洛、資源利用率高
缺點(diǎn):第一次加載時(shí)反應(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)建實(shí)例
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
靜態(tài)內(nèi)部類模式
優(yōu)點(diǎn):確保線程安全旧乞、保證單例裁赠、延遲了單例的實(shí)例化
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 {
//反序列化直接返回對(duì)象,而不是生成新對(duì)象
return instance;
}
因?yàn)樾蛄谢梢詫⒁粋€(gè)單例的實(shí)例對(duì)象寫入磁盤,然后再讀出來(lái),從而有效的獲取一個(gè)實(shí)例,
即使構(gòu)造函數(shù)私有,反序列化依舊可以通過(guò)特殊途徑獲得新的實(shí)例
枚舉單例
線程安全且單例,反序列化情況也不會(huì)生成新的實(shí)例
public enum Singleton {
INSTANCE;
}
個(gè)人博客 請(qǐng)戳:http://lutils.cn