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