定義:確保一個類只有一個實(shí)例,并自行實(shí)例化向整個提供這個實(shí)例。
單例類的3個要素:
1、一個私有的構(gòu)造方法(保證外界無法實(shí)例化該對象)
2、一個私有的靜態(tài)實(shí)例變量
3、一個公有的獲取實(shí)例變量的方法
兩中模式:
1、餓漢模式
在類裝載(編譯的時候)的時候?qū)嵗?/p>
public class Singleton{
private Singleton(){}
private static Singleton mInstance = new Singleton();
public Singleton getInstance(){
return mInstance;
}
}
餓漢式存在的問題:
如果構(gòu)造方法中存在過多的處理,會導(dǎo)致加載這個類時比較慢,可能引起性能問題。
如果使用餓漢式的話,只進(jìn)行了類的裝載,并沒有實(shí)質(zhì)的調(diào)用,會造成資源的浪費(fèi)。
2、懶漢模式
public classs Singleton{
private static Singleton mInstance;
private Singleton(){}
public Singleton getInstance(){
if( null == mInstance){
mInstance = new Singleton();
}
return mInstance;
}
}
上述的代碼在多個線程密集調(diào)用getInstance時,存在創(chuàng)建多個實(shí)例的可能。比如線程A進(jìn)入null == sInstance這段代碼塊,而在A線程未創(chuàng)建完成實(shí)例時,如果線程B也進(jìn)入了該代碼塊,必然會造成兩個實(shí)例的產(chǎn)生。
懶漢模式優(yōu)化
public classs Singleton{
private static Singleton mInstance;
private Singleton(){}
public Singleton synchronized getInstance(){
if( null == mInstance){
mInstance = new Singleton();
}
return mInstance;
}
}
使用synchrnozed修飾getInstance方法可能是最簡單的一個保證多線程保證單例唯一性的方法。
synchronized修飾的方法后,當(dāng)某個線程進(jìn)入調(diào)用這個方法,該線程只有當(dāng)其他線程離開當(dāng)前方法后才會進(jìn)入該方法。所以可以保證getInstance在任何時候只有一個線程進(jìn)入。
關(guān)于保證多線程下單例唯一的還有兩種方法如下,可以在參考原文中找到,因?yàn)檫€不是特別理解,所以先不寫在一起。
1、雙重加鎖
2、static機(jī)制
存在的疑問
1、真的只有一個實(shí)例嗎
2、能否被繼承
3、和靜態(tài)變量的區(qū)別
4、關(guān)于GC
應(yīng)用
1、數(shù)據(jù)庫連接類
參考原文:http://droidyue.com/blog/2015/01/11/looking-into-singleton/