本篇內(nèi)容介紹了“web設(shè)計(jì)模式中的單例模式是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)10多年成都企業(yè)網(wǎng)站建設(shè)服務(wù);為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì)及高端網(wǎng)站定制服務(wù),成都企業(yè)網(wǎng)站建設(shè)及推廣,對(duì)除甲醛等多個(gè)領(lǐng)域擁有豐富的網(wǎng)站運(yùn)維經(jīng)驗(yàn)的網(wǎng)站建設(shè)公司。
單例模式 (Singleton Pattern)使用的比較多,比如我們的 controller 和 service 都是單例的,但是其和標(biāo)準(zhǔn)的單例模式是有區(qū)別的。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。這種模式涉及到一個(gè)單一的類,該類負(fù)責(zé)創(chuàng)建自己的對(duì)象,同時(shí)確保只有單個(gè)對(duì)象被創(chuàng)建。這個(gè)類提供了一種訪問其唯一的對(duì)象的方式,可以直接訪問,不需要實(shí)例化該類的對(duì)象。
單例模式的結(jié)構(gòu)很簡(jiǎn)單,只涉及到一個(gè)單例類,這個(gè)單例類的構(gòu)造方法是私有的,該類自身定義了一個(gè)靜態(tài)私有實(shí)例,并向外提供一個(gè)靜態(tài)的公有函數(shù)用于創(chuàng)建或獲取該靜態(tài)私有實(shí)例。
單例模式分為懶漢單例和餓漢單例;餓漢單例代碼很簡(jiǎn)單,顧名思義,餓漢單例就是類初始化的時(shí)候就將該單例創(chuàng)建,示例代碼如下:
public class Singleton {
private static final Singleton singleton = new Singleton();
//限制產(chǎn)生多個(gè)對(duì)象
private Singleton(){
}
//通過該方法獲得實(shí)例對(duì)象
public static Singleton getSingleton(){
return singleton;
}
//類中其他方法,盡量是 static
public static void doSomething(){
}
}但是懶漢單例就不那么簡(jiǎn)單了,懶漢單例是在訪問這個(gè)類的實(shí)例的時(shí)候先判斷這個(gè)類的實(shí)例是否創(chuàng)建好了,如果沒創(chuàng)建好就要先創(chuàng)建這個(gè)單例。也就是說懶漢單例是第一次訪問的的時(shí)候創(chuàng)建單例,而不是初始化階段。這將會(huì)導(dǎo)致一個(gè)問題,如果在多線程場(chǎng)景下,多個(gè)線程同時(shí)訪問這個(gè)單例都發(fā)現(xiàn)其未被創(chuàng)建,那么這些線程就會(huì)分別創(chuàng)建實(shí)例,那么這個(gè)單例模式就不那么單例了——實(shí)例被多次創(chuàng)建。在阿里開發(fā)手冊(cè)中有兩條就是和懶漢單例相關(guān)的,告訴我們要如何去避免這種情況,第六節(jié)的第一條 和第十二條:
(六)并發(fā)處理
1.【強(qiáng)制】獲取單例對(duì)象需要保證線程安全,其中的方法也要保證線程安全。
說明:資源驅(qū)動(dòng)類、工具類、單例工廠類都需要注意。
【推薦】在并發(fā)場(chǎng)景下,通過雙重檢查鎖(double-checked locking)實(shí)現(xiàn)延遲初始化的優(yōu)
化問題隱患,推薦解
決方案中較為簡(jiǎn)單一種(適用于 JDK5 及以上版本),將目標(biāo)屬性聲明為 volatile 型。
反例:
class Singleton { private Helper helper = null; public Helper getHelper() { if (helper == null) synchronized(this) { if (helper == null) helper = new Helper(); } return helper; } // other methods and fields... }
volatile 關(guān)鍵字的作用和雙重檢查鎖在我以往的博客中介紹過,文章地址https://mp.weixin.qq.com/s/r52hmD71TtiJjlOzQUvRlA 這篇博客介紹了并發(fā)的一些知識(shí),小伙伴有空可以讀一讀。在這里 volatile 關(guān)鍵字的作用就是保證數(shù)據(jù)的可見性,雙重檢查鎖是提高代碼性能。下面我們分析一下手冊(cè)中的反例:
其中它的雙重檢測(cè)鎖指的是這段代碼:
if (helper == null) synchronized(this) {
if (helper == null)
helper = new Helper();
}這里如果不用雙重檢測(cè)鎖的話只能在整個(gè) getHelper 方法上上鎖,因?yàn)檫@個(gè)方法必須要保證在并發(fā)情況下只有一個(gè)線程會(huì)執(zhí)行helper = new Helper(); ,這段代碼。也就是說代碼 會(huì)成為這樣:
public synchronized Helper getHelper() {
if (helper == null) {
if (helper == null)
helper = new Helper();
}
return helper;
}整個(gè)方法上鎖性能明顯是不好的,鎖的粒度變大了;雙重檢查鎖里面為什么要做兩次 if 判斷呢,這個(gè)問題留給讀者思考,并不是特別難的問題。但是反例里面沒有考慮到可見性的問題——假設(shè)a線程和b線程同時(shí)訪問 getHelper 方法,然后 b 線程被阻塞住,a線程發(fā)現(xiàn)helper 未被實(shí)例化,于是執(zhí)行new方法,然后釋放鎖;此時(shí)b線程進(jìn)來,或許我們直觀的感受是b線程發(fā)現(xiàn)屬性被實(shí)例化直接返回helper,但實(shí)際上不是,當(dāng)一個(gè)線程修改了線程共享的公共資源的時(shí)候(此處是helper屬性)其他線程未必會(huì)被通知到屬性被修改,因此b線程有可能發(fā)現(xiàn) helper 還是null 也有可能b線程知道 helper 被賦值了。使用volatile 就可以避免這種情況的發(fā)生。因此正確的代碼應(yīng)該是這樣的:
class Singleton {
private volatile Helper helper = null;
public Helper getHelper() {
······
}
// other methods and fields...
}“web設(shè)計(jì)模式中的單例模式是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
網(wǎng)頁(yè)標(biāo)題:web設(shè)計(jì)模式中的單例模式是什么
文章轉(zhuǎn)載:http://chinadenli.net/article36/jpcjpg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)、企業(yè)建站、小程序開發(fā)、云服務(wù)器、網(wǎng)站改版、虛擬主機(jī)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)