定義
單例模式是指某個(gè)類只有一個(gè)實(shí)例溉仑,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例荐糜。
實(shí)現(xiàn)思想
在類的內(nèi)部通過(guò)構(gòu)造一個(gè)private的構(gòu)造方法卧秘,外部不能調(diào)用其構(gòu)造方法鳖链,所以外部無(wú)法實(shí)例化姆蘸。
單例模式有以下特點(diǎn)
1、單例類只能有一個(gè)實(shí)例芙委。
2逞敷、單例類必須自己創(chuàng)建自己的唯一實(shí)例厢钧。
3鲸湃、單例類必須給所有其他對(duì)象提供這一實(shí)例懈糯。
單例模式分為餓漢式和懶漢式兩種
餓漢就是類一旦加載甸赃,就把單例初始化完成画髓,保證獲取單例的時(shí)候徘郭,單例是已經(jīng)存在的了端朵。
懶漢比較懶液肌,只有當(dāng)調(diào)用獲取單例方法的時(shí)候,才回去初始化這個(gè)單例焰络。
懶漢單例模式
//懶漢式單例類.在第一次調(diào)用的時(shí)候?qū)嵗约?/p>
public class Singleton {
private Singleton() {}
private static Singleton single=null;
//靜態(tài)工廠方法
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
懶漢式單例在并發(fā)環(huán)境下很可能出現(xiàn)多個(gè)實(shí)例戴甩,所以要注意線程安全的問(wèn)題,有以下三種方式對(duì)懶漢模式進(jìn)行改造闪彼,都是對(duì)getInstance這個(gè)方法改造甜孤,保證了懶漢式單例的線程安全。
1畏腕、在getInstance方法上加同步
public static synchronized Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
2缴川、雙重檢查鎖定
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
3、靜態(tài)內(nèi)部類
public class Singleton {
private static class LazyHolder {
private static final Singleton INSTANCE = newSingleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
使用靜態(tài)內(nèi)部類的方式實(shí)現(xiàn)單例模式描馅,比上面1把夸、2都好一些,既實(shí)現(xiàn)了線程安全铭污,又避免了同步帶來(lái)的性能影響恋日。
餓漢單例模式
//餓漢式單例類.在類初始化時(shí),已經(jīng)自行實(shí)例化
public class Singleton1 {
private Singleton1() {}
private static final Singleton1 single = newSingleton1();
//靜態(tài)工廠方法
public static Singleton1 getInstance() {
return single;
}
}
餓漢式在類創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對(duì)象供系統(tǒng)使用嘹狞,以后不再改變岂膳,所以天生是線程安全的
單例模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
1、減少內(nèi)存開(kāi)銷磅网,尤其是頻繁的創(chuàng)建和銷毀實(shí)例谈截,減少gc
2、避免對(duì)資源對(duì)過(guò)多占用涧偷。
?缺點(diǎn):
1簸喂、違背了“單一職責(zé)原則”,一個(gè)類只重視內(nèi)部關(guān)系嫂丙,而忽略外部關(guān)系娘赴。
2、不適用于變化對(duì)象跟啤。
3诽表、濫用單例會(huì)出現(xiàn)一些負(fù)面問(wèn)題,如為節(jié)省資源將數(shù)據(jù)庫(kù)連接池對(duì)象設(shè)計(jì)為單例隅肥,可能會(huì)導(dǎo)致共享連接池對(duì)象對(duì)程序過(guò)多而出現(xiàn)連接池溢出竿奏。如果實(shí)例化的對(duì)象長(zhǎng)時(shí)間不被利用,系統(tǒng)會(huì)認(rèn)為是垃圾而被回收腥放,這樣將導(dǎo)致對(duì)象狀態(tài)丟失泛啸。