確保一個類只有一個實例,并且自行實例化并向系統(tǒng)提供這個實例
關鍵點
- 構造方法不對外開發(fā)吏夯,構造方法私有化
- 通過一個靜態(tài)方法或者枚舉返回對象
- 確保單例類的對象有且只有一個震檩,尤其在多線程環(huán)境下
- 反序列化時不會重新構造對象
餓漢模式
public class Singleton{
private static final mSingleton = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return mSingleton;
}
}
這種模式在聲明的時候初始化對象,確保了類的唯一性善镰。這個實現(xiàn)的核心在于構造方法的私有化是目,使得外部程序不能通過new的方式來構造對象谤饭,而Singleton類通過一個靜態(tài)方法返回一個靜態(tài)對象。
懶漢模式
public class Singleton {
private static Singleton sInstance;
private Singleton () {}
public static synchronized Singleton getInstance {
if(sInstance == null) {
sInstance = new Singleton();
}
return sInstance;
}
}
synchronized關鍵字就是getInstance的同步方法,多進程情況下保證單例對象唯一性的手段揉抵。不過每次調用這個方法都會進行同步亡容,這樣會消耗不必要的資源,也是存在的最大問題冤今。一般不建議使用闺兢。
Double Check Lock(DCL)模式
DCL方式實現(xiàn)的單例模式的優(yōu)點是既能夠在需要是才初始化單例,又能夠保證線程安全戏罢,且單例對象初始化后調用getInstance不進行同步鎖屋谭。
public class Singleton {
private static Singleton sInstance = null;
private Singleton(){}
public static Singleton getInstance(){
if(sInstance == null){
synchronized(Singleton.class){
if(sInstance == null) {
sInstance = new Singleton();
}
}
}
return sInstance;
}
}
上面代碼有兩層判斷:第一層判斷是為了避免不必要的同步,第二層判斷是為了在null的情況下創(chuàng)建實例龟糕。
DCL模式的優(yōu)點:資源利用率高桐磁,效率高。缺點:第一次加載反應稍慢讲岁。
DCL模式是使用單例模式最多的實現(xiàn)我擂。(jdk6以上使用)
靜態(tài)內部類單例模式
public class Singleton {
private Singleton () {}
public static Singleton getInstance () {
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
}
當?shù)谝淮渭虞dSingleton類是并不會初始化sInstance,只有在第一次調用Singleton的getInstance方法時才有被初始化缓艳。這種方式不僅能保證線程安全校摩,也能夠保證單例對象的唯一性,同時也延遲了單例的實例化阶淘,為首選的單例實現(xiàn)方式衙吩。
優(yōu)點
- 單例模式在內存只存在一個實例,減少內存開支舶治,特別是一個對象需要頻繁地創(chuàng)建分井,銷毀時,單例模式的優(yōu)勢會特別明顯
- 減少系統(tǒng)的性能開銷霉猛。
- 避免對資源的多重占用,例如一個文件的寫入操作珠闰,由于只存在一個實例在內存中惜浅,故可以避免對同一個資源文件同時進行寫入操作
- 單例模式可以在全局設置訪問點,優(yōu)化和共享資源訪問伏嗜。例如坛悉,可以設計一個單例類,負責所有數(shù)據(jù)表的映射操作
缺點
- 單例模式沒有接口承绸,擴展很困難裸影,若要擴展,除了修改代碼幾乎沒有第二種途徑可以實現(xiàn)
- 單例模式如果持有Context军熏,很容易出現(xiàn)內存泄漏轩猩,此時傳遞給單例對象的Context最好是Application Context.