摘要:第二種懶漢式線程不安全對象為空才去實例化懶漢式是在使用的時候才會去加載,不過當多次同時去加載的時候就會存在線程安全問題。
單例模式,是一種常用的軟件設計模式,在它的核心結構中只包含一個被稱為單例的特殊類,通過單例模式可以保證系統中一個類只有一個實例。即一個類只有一個對象實例。
第一種:餓漢式
public class SingleEasy { private SingleEasy(){ } //類初始化的時候就已經加載 private static SingleEasy singleEasy=new SingleEasy(); public static SingleEasy getInstance(){ return singleEasy; } }
餓漢式的話不存在多線程同步加載的問題,類初始化時就已經加載,做不到使用的時候才加載。
第二種:懶漢式(線程不安全)
public class SingleNotEmptyEasy { private static SingleNotEmptyEasy singleNotEmptyEasy; private SingleNotEmptyEasy(){ } public static SingleNotEmptyEasy getInstance(){ //對象為空才去實例化 if(singleNotEmptyEasy==null){ singleNotEmptyEasy=new SingleNotEmptyEasy(); } return singleNotEmptyEasy; } }
懶漢式是在使用的時候才會去加載,不過當多次同時去加載的時候就會存在線程安全問題。
第三種:懶漢式(線程安全)
public class SingleNotEmptyEasy { private static SingleNotEmptyEasy singleNotEmptyEasy; private SingleNotEmptyEasy(){ } public static synchronized SingleNotEmptyEasy getInstance(){ //對象對空才去實例化 if(singleNotEmptyEasy==null){ singleNotEmptyEasy=new SingleNotEmptyEasy(); } return singleNotEmptyEasy; } }
就是在第二種的getInstance方法上面加了一個同步鎖synchronized,每次在使用加載的時候都會先去校驗,如果已經有在加載了,就不會去加載,而是要等前面的加載完了,才會去加載,這樣線程安全,但是每次都去校驗synchronized會造成效率的下降。
第四種:DCL
public class DCLSingle { private volatile static DCLSingle dclSingle; private DCLSingle(){ } public static DCLSingle getInstance(){ if(dclSingle==null){ synchronized (DCLSingle.class){ if(dclSingle==null){ dclSingle=new DCLSingle(); } } } return dclSingle; } }
DCL模式的不同是沒有將同步鎖加載方法上,而是加在代碼塊里面,如果單例對象不為空就直接返回,如果為空就會走到加了同步鎖的代碼塊中,還會進行第二次校驗,這樣子提高了效率,同時也保證了線程的安全,這種模式還涉及到一個java的關鍵字volatile,加了volatile,可以保證無論何時讀取這個變量,都是讀到內存中最新的值,無論何時寫這個變量,都可以立即寫到內存中。
第五種:內部類模式
public class InnnerClassSingle { private InnnerClassSingle(){ } private static class SingleHolder{ private static InnnerClassSingle innnerClassSingle=new InnnerClassSingle(); } public static InnnerClassSingle getInstance(){ return SingleHolder.innnerClassSingle; } }
內部類模式是一種比較優雅的餓漢式,它是在InnnerClassSingle內中再建一個SingleHolder內部類,在內部類中創建一個InnnerClassSingle對象,通過內部類調用加載實例化,這樣子不會隨著類的加載的而實例化,做到了使用的時候才實例化。
第六種:枚舉模式
public enum EnumManager { SDCardManager(10){ @Override public EnumManager getSingle() { return SDCardManager; } } , HttpManager(1){ @Override public EnumManager getSingle() { return HttpManager; } }; public abstract EnumManager getSingle(); private EnumManager(int type){ } }
這里需要注意的是枚舉的構造方法是私有的,變量的聲明要在構造方法之前。
歡迎加入學習交流群569772982,大家一起學習交流。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70505.html
摘要:總結單例是運用頻率很高的模式,因為客戶端沒有高并發的情況,選擇哪種方式并不會有太大的影響,出于效率考慮,推薦使用和靜態內部類實現單例模式。 單例模式介紹 單例模式是應用最廣的模式之一,也可能是很多人唯一會使用的設計模式。在應用單例模式時,單例對象的類必須保證只用一個實例存在。許多時候整個系統只需要一個全局對象,這樣有利于我么能協調整個系統整體的行為。 單例模式的使用場景 確保某個類有且...
摘要:不符合設計模式中的單一職責的概念。引入代理實現單例模式引入代理實現單例模式的特點我們負責管理單例的邏輯移到了代理類中。的單例模式對比在以上的代碼中實現的單例模式都混入了傳統面向對象語言的特點。 聲明:這個系列為閱讀《JavaScript設計模式與開發實踐》 ----曾探@著一書的讀書筆記 1.單例模式的特點和定義 保證一個類僅有一個實例,并且提供一個訪問它的全局訪問點。 2.傳統面向對...
摘要:如果需要防范這種攻擊,請修改構造函數,使其在被要求創建第二個實例時拋出異常。單例模式與單一職責原則有沖突。源碼地址參考文獻設計模式之禪 定義 單例模式是一個比較簡單的模式,其定義如下: 保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。 或者 Ensure a class has only one instance, and provide a global point of ac...
摘要:在設計模式一書中,將單例模式稱作單件模式。通過關鍵字,來保證不會同時有兩個線程進入該方法的實例對象改善多線程問題為了符合大多數程序,很明顯地,我們需要確保單例模式能在多線程的情況下正常工作。 在《Head First 設計模式》一書中,將單例模式稱作單件模式。這里為了適應大環境,把它稱之為大家更熟悉的單例模式。 一、了解單例模式 1.1 什么是單例模式 單例模式確保一個類只有一個實例,...
閱讀 2416·2021-11-25 09:43
閱讀 1195·2021-09-07 10:16
閱讀 2603·2021-08-20 09:38
閱讀 2936·2019-08-30 15:55
閱讀 1449·2019-08-30 13:21
閱讀 883·2019-08-29 15:37
閱讀 1435·2019-08-27 10:56
閱讀 2093·2019-08-26 13:45