[設計模式]單例模式(懶漢式和餓漢式)
單例模式(Singleton pattern)
定義:
一種常見的軟體設計模式
目的:
應用該模式的類一個類只有一個例項。即一個類只有一個物件例項
瞭解了定義和目的後我們先來看一下兩種單例模式:
1.懶漢式(lazy):
概念:
顧名思義,通俗的講,懶漢式就是比較懶的方法,只有當別人呼叫它的時候,它才去建立這個例項。
程式碼示例:
class LSingle{ private static Instance_instance = null; private LSingle(){} public static Instance getInstance(){ if(_instance==null){ _instance = new Instance(); } }
分析:
首先建立了一個名為LSingle的類,類裡面有一個私密的靜態成員物件和私密的構造方法,我們在這裡主要看那個靜態成員物件(Instance_instance),不難看出在類裡並沒有例項化它,而是在下面的公開的靜態方法裡做了一個判斷,如果_instance==null,才去建立這個物件,這樣其他類在呼叫這個公開的靜態方法時,就會先做判斷,只有當它==null的時候,才會去建立,這確實保證一個例項的目的。
優點:
使用懶載入(就是懶漢式),速度是比較快的(相對於餓漢式來講),因為它不需要在類載入的時候就建立物件。
缺點:
在多執行緒情況下,不能保證一個例項(只建立一次物件),舉例,執行緒A和執行緒B同時進入了if(_instance==null),執行緒A和執行緒B都滿足建立條件,故建立了兩個例項,雖然用同步鎖可以解決,但是效率很低下。
解決多執行緒下不是一個單例物件問題:
程式碼改造:
class LSingle{ private static Instance_instance = null; private LSingle(){} //建立一個鎖物件 public static Object lock = new Object(); public static Instance getInstance(){ if(_instance==null){ //同步鎖,保證同時只能有一個執行緒進入到這裡 synchronized(lock){ //再次判斷是否為null if(_instance==null){ _instance = new Instance(); } } } }
2.餓漢式(Hungry)
概念:
餓漢式恰巧與懶漢式相反,聽名字也可以猜個一二,餓漢式,比較餓嘛,所以它在這個物件載入的時候就已經把例項給你建立好了,等待你使用
程式碼示例:
class ESingle{ private static Instance_instance = new Instance;//注意區別,直接作為成員物件建立 private ESingle(){} public static Instance getInstance(){ return _instance;//直接返回之前已經建立好的例項 } }
分析:
首先建立了一個名為ESingle的類,單例物件直接作為類的私密靜態成員來建立,下面提供了一個公開的靜態方法,返回的是之前建立好的例項物件。
優點:
使用餓漢式可以保證多執行緒下一個例項的目的(也就是單例),因為即使多個執行緒同時進入這個方法,返回的也只是一個例項物件,(注意:是多個執行緒進入到這個方法,而不是這個類),而這個物件在載入時(new時),就已經建立完畢了,所以不會出現懶漢式的那種情況
缺點:
由於單例物件是在類載入的時候完成的,所以比較耗費資源(與懶漢式相比較)