前言: 在總結okHttp的時候,為了管理網路請求使用到了單例模式,晚上實在沒啥狀態了,靜下心來學習總結一下使用頻率最高的設計模式單例模式。 單例模式: 單例模式確保某個類只有一個實例,而且自行實例化並向整個系統提供這個實例。 單例特點: 單例類只能有一個實例。 單例類必須自己創建自己的唯一實例。 ...
前言:
在總結okHttp的時候,為了管理網路請求使用到了單例模式,晚上實在沒啥狀態了,靜下心來學習總結一下使用頻率最高的設計模式單例模式。
單例模式:
單例模式確保某個類只有一個實例,而且自行實例化並向整個系統提供這個實例。
單例特點:
- 單例類只能有一個實例。
- 單例類必須自己創建自己的唯一實例。
- 單例類必須給所有其他對象提供這一實例。
單例分類:
1).懶漢單例
(1)非線程安全實現
public class Singleton { private Singleton(){ } private static Singleton instance; public static Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } }
(2)線程安全實現方式一 方法加同步 這種實現方式效率不高
public class Singleton { private Singleton(){ } private static Singleton instance; public static synchronized Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } }
(3.)線程安全實現方式二 雙重檢查鎖定
public class Singleton{ private static Singleton single; //聲明靜態的單例對象的變數 private Singleton(){} //私有構造方法 public static Singleton getSingle(){ //外部通過此方法可以獲取對象 if(single == null){ synchronized (Singleton.class) { //保證了同一時間只能只能有一個對象訪問此同步塊 if(single == null){ single = new Singleton(); } } } return single; //返回創建好的對象 } }
2.)餓漢式單例類
餓漢式在類創建的同時就已經創建好一個靜態的對象供系統使用,以後不再改變,所以天生是線程安全的。
public class Singleton { private Singleton(){ } private final static Singleton instance = new Singleton(); private static Singleton getInstance(){ return instance; } }
3.)內部類式單例類
內部類式中,實現了延遲載入,只有我們調用了getInstance(),才會創建唯一的實例到記憶體中.並且也解決了懶漢式中多線程的問題.解決的方式是利用了Classloader的特性,既實現了線程安全,又避免了同步帶來的性能影響。
public class Singleton{ private Singleton(){ } private static class SingletonHolder(){ private static Singleton instance = new Singleton(); } private static Singleton getInstance(){ return SingletonHolder.instance; } }
4.)枚舉類單例
《Effective Java》作者推薦使用的方法,優點:不僅能避免多線程同步問題,而且還能防止反序列化重新創建新的對象
public enum Singleton { /** * 定義一個枚舉的元素,它就代表了Singleton的一個實例。 */ uniqueInstance; /** * 單例可以有自己的操作 */ public void doSomeThing(){ //功能處理 } }
5.)懶漢和餓漢區別
(1)初始化角度
餓漢就是類一旦載入,就把單例初始化完成,保證getInstance的時候,單例是已經存在的了,而懶漢比較懶,只有當調用getInstance的時候,才回去初始化這個單例
(2)線程安全形度
餓漢式天生就是線程安全的,可以直接用於多線程而不會出現問題,懶漢式本身是非線程安全的,需要自己實現線程安全的方法。