摘要:既能保證延遲加載,又能保證線程安全枚舉上面的四種方案都有兩個弊端需要額外的工作進行序列化,否則每次反序列化的結果都是一個新的實例可通過反射機制強行調用私有構造器實現創建多個對象而這種方案完美的解決了上述兩種問題
一.什么是單例模式?
單例是指在程序中某個類只能有一個實例,一些管理器和控制器常被設計成單例模式(如Spring容器的bean實例默認都是單例模式存在的)
二.單例有什么好處?
(1)避免對象的重復創建,減小時間和內存開銷 (2)避免由于操作多個對象導致邏輯錯誤,可以全局統一管理控制
三.怎樣創建單例模式?
(1)餓漢模式
public class Singleton1 { // 私有化構造函數,保證其它類不能實例化此類 private Singleton1(){} private static Singleton1 instance = new Singleton1(); //給外界提供一個獲取該實例的方法 public static Singleton1 getInstance() { return instance; } }
餓漢模式是實例在類加載的時候創建 好處:避免線程同步問題 缺點:即使這個單例不會被用到也會創建,浪費內存資源
(2)懶漢模式
public class Singleton2 { private Singleton2(){} private static Singleton2 instance = null; public static Singleton2 getInstance() { if(instance == null){ return new Singleton2(); } return instance; } }
懶漢模式是單例在需要的時候才會去創建 好處:按需創建,避免內存資源浪費 壞處:會有線程安全問題產生(需要加鎖解決線程同步問題)
(3)雙重校驗鎖
public class Singleton3 { private Singleton3(){} private static volatile Singleton3 instance = null; public static Singleton3 getInstance() { if(instance == null){ synchronized (Singleton3.class){ instance = new Singleton3(); } } return instance; } }
上面說到的懶漢模式加同步鎖最先想到的可能是在getInstance外直接加synchronized,但仔細想想,每次來拿該對象都需要判斷對象鎖,這樣無疑會降低代碼執行效率,所以在同步前先判斷對象是否為空,如果不為空直接將對象給它,不需要進行同步操作(這樣層序運行過程中最多也只有一次同步鎖的判斷)你一定還發現對象聲明的修飾符多了一個volatile,這就是第二把鎖,它能起到禁止指令重排序優化的作用,這樣就避免了對象內存地址被賦給instance字段但是構造函數還沒調用。(具體原因詳見---關于volatile的理解最后一段)
(4)靜態內部類
public class Singleton4 { private static class Singleton{ public static Singleton4 instance = new Singleton4(); } private Singleton4(){} public static Singleton4 newInstance(){ return Singleton.instance; } }
與餓漢模式一樣同樣是利用類加載機制來創建實例,因此不存在多線程并發問題,不同的是它是在內部類里去加載這個實例,所以只要不使用這個內部類,JVM就不會加載這個單例類,也就不會創建對象,實現了懶漢式的延遲加載。既能保證延遲加載,又能保證線程安全
(5)枚舉
public enum Singleton5 { instance; public void whateverMethod(){} }
上面的四種方案都有兩個弊端:
1)需要額外的工作進行序列化,否則每次反序列化的結果都是一個新的實例 2)可通過反射機制強行調用私有構造器實現創建多個對象
而這種方案完美的解決了上述兩種問題
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69082.html
摘要:在設計模式一書中,將單例模式稱作單件模式。通過關鍵字,來保證不會同時有兩個線程進入該方法的實例對象改善多線程問題為了符合大多數程序,很明顯地,我們需要確保單例模式能在多線程的情況下正常工作。 在《Head First 設計模式》一書中,將單例模式稱作單件模式。這里為了適應大環境,把它稱之為大家更熟悉的單例模式。 一、了解單例模式 1.1 什么是單例模式 單例模式確保一個類只有一個實例,...
摘要:不符合設計模式中的單一職責的概念。引入代理實現單例模式引入代理實現單例模式的特點我們負責管理單例的邏輯移到了代理類中。的單例模式對比在以上的代碼中實現的單例模式都混入了傳統面向對象語言的特點。 聲明:這個系列為閱讀《JavaScript設計模式與開發實踐》 ----曾探@著一書的讀書筆記 1.單例模式的特點和定義 保證一個類僅有一個實例,并且提供一個訪問它的全局訪問點。 2.傳統面向對...
摘要:防止指令重排序防止時指令重排序導致其他線程獲取到未初始化完的對象。枚舉類默認枚舉實例的創建是線程安全的,所以不需要擔心線程安全的問題。 單例模式是23種GOF模式中最簡單,也是最經常出現的一種設計模式,也是面試官最常愛考的一種模式,為什么呢?因為單例模式足夠簡單,編寫一個單例模式代碼幾分鐘就能搞定,所以設計模式中面試官通常會選取單例模式作為出題。下面把單例模式分幾個點,分別說說哪些地方...
摘要:此時我們創建的對象內保存靜態變量通過取值器訪問,最后將這個對象作為一個單例放在全局空間里面作為靜態變量單例對象供他人使用。 單例模式 又被稱為單體模式,是只允許實例化一次的對象類。有時我們也用一個對象來規劃一個命名空間,井井有條的管理對象上面的屬性和方法。 傳統的面向對象語言中單例模式的實現,均是單例對象從類中創建而來,在以類為中心的語言中,這是很常見的做法。如果需要某個對象,就必須先...
摘要:但是,這并不是采用單例的唯一原因。使用命名空間單例模式也被稱為模塊設計模式。函數內部聲明了一些局部函數和或變量。緊隨函數聲明放置即可立即執行外部函數,并將所得的對象文字費賠給變量。 JavaScript設計模式-第一部分:單例模式、組合模式和外觀模式 設計模式是一些可靠的編程方式,有助于保證代碼更加易于維護、擴展及分離,所有設計模式在創建大型JavaScript應用程序時均不可或缺 單...
摘要:單例模式概述單例模式是一種對象創建模式,用于產生一個類的具體事例。所以解決了線程安全問題參考失效原因和解決方案中單例模式的缺陷及單例的正確寫法懶漢式靜態內部類私有構造器獲取單例的方法靜態內部類持有單例作為靜態屬性。 單例模式概述 單例模式是一種對象創建模式,用于產生一個類的具體事例。使用單例模式可以確保整個系統中單例類只產生一個實例。有下面兩大好處: 對于頻繁創建的對象,節省初第一...
閱讀 2695·2023-04-25 17:58
閱讀 2978·2021-11-15 11:38
閱讀 2378·2021-11-02 14:48
閱讀 1185·2021-08-25 09:40
閱讀 1823·2019-08-30 15:53
閱讀 1093·2019-08-30 15:52
閱讀 1031·2019-08-30 13:55
閱讀 2437·2019-08-29 15:21