Android 設計模式-單例模式,android設計模式
Android 設計模式-單例模式什麼情況下需要單例模式?
- 一些類提供公用功能供別人調用,本身不會處理商務邏輯
- 類會被許多類和線程調用
設計單例模式
public class Singleton{private static Singleton mSingleton;private Singleton(){}public static Singleton getInstance(){if(mSingleton == null){ mSingleton = new Singleton();\\A } return mSingleton; }}
上面的做法在多線程的時候會出現問題,比如有兩個線程同時調用getInstance(),這時會new兩個對象出來。
單例模式改進1
public class Singleton{private static Singleton mSingleton;private Singleton(){}public static Singleton getInstance(){ synchronized(Singleton.class){ if(mSingleton == null){ mSingleton = new Singleton();\\A } return mSingleton; } }}
這種方式還是會有問題,就是高並發情況下多線程去搶奪鎖,假如有幾百個線程,其中有一個運氣比較差,這個線程就會出現一直去getInstance,資源一直返回不回去,UI也不會得到更新。
單例模式改進2
public class Singleton{private volatile static Singleton mSingleton;private Singleton(){}public static Singleton getInstance(){ if(mSingleton == null){\\A synchronized(Singleton.class){\\C if(mSingleton == null) mSingleton = new Singleton();\\B } } return mSingleton; }}
註:volatile是防止cpu進行指令重排序,防止代碼順序被更改。
這種方式比較好的地方在於第一次建立執行個體時候就會同步所有的線程,以後再擷取執行個體就會直接返回。
但是看代碼好像還是有人會有疑問,為什麼需要兩次判斷為null?
其實這個意義在於防止多個線程同時進入第一個if內,比如說線程A執行到A行,線程B執行到B行,線程B還沒有返回。當線程A執行到C行,這時線程B初始化執行個體完畢,如果沒有裡面的再一次判斷就會產生兩個執行個體!所以兩次的判斷null還是有意義的。