單例模式是面試時常考的一個設計模式,面試官常常要求面試者實現一個單例模式。那麼,一個面試者的實現可以分為三個層次:0層,寫不出來;1層,單執行緒下的單例模式;2層:用double-checked locking實現的單例模式;3層,用內部類實現的單例模式。下面分別描述。
1,單執行緒下的單例模式
只要知道單例模式的意義--
“
單例模式是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例類的特殊類。通過單例模式可以保證系統中一個類只有一個例項而且該例項易於外界訪問,從而方便對例項個數的控制並節約系統資源。如果希望在系統中某個類的物件只能存在一個,單例模式是最好的解決方案。--百度百科
”
單執行緒下實現如下:
class Singleton1{ //(2)靜態例項 private static Singleton1 instance; //(3)提供給外部介面 public static Singleton1 getInstance(){ if(instance==null){ instance=new Singleton1(); } return instance; } //(1),private的建構函式 private Singleton1(){ } public void amethod(){ } }
2,多執行緒下的單例模式
上面的程式碼在單執行緒下沒問題,但是在多執行緒下就有問題了。比如A和B兩個執行緒同時呼叫getInstance方法,A執行完了nstance==null,但是時間片被B搶到,此時B執行到instance==null,條件為true,B建立instance,接著輪到了A,A繼續執行,那麼第二個instance被建立出來了。為了避免這一現象,必須採取同步措施,這就是所謂的double-checed lock:
class Singleton2{ private static Singleton2 instance; public static Singleton2 getInstance(){ if(instance==null){ synchronized(Singleton2.class){ if(instance==null){ instance=new Singleton2(); } } } return instance; } }
3, 通過內部類實現單例模式。
原理就是JVM內部機制能夠保證當一個類被載入的時候,這個類的載入過程是互斥的
public class Singleton{ private Singleton(){ } private static class SingletonContainer{ private static Singleton instance = new Singleton(); } public static Singleton getInstance(){ return SingletonContainer.instance; } }
這樣在第一次呼叫getInstance的時候導致SingletonContainer類的被載入和初始化,這個過程是互斥的,因此不存在instance會被建立多次的情況。