Java 單例模式線程安全問(wèn)題
Java 單例模式線程安全問(wèn)題
SpringIOC容器默認(rèn)提供bean的訪問(wèn)作用域是單例模式。即在整個(gè)application生命周期中,只有一個(gè)instance。因此在多線程并發(fā)下,會(huì)有線程安全風(fēng)險(xiǎn)。我們?cè)贛VC框架下的servlet就是線程安全的。由于該servlet是在客戶端,多并發(fā)相對(duì)少,但是對(duì)于web service端,需要考慮到。
ThreadLocal類:為每一個(gè)線程提供了一個(gè)獨(dú)立的變量(實(shí)例)副本,從各將各個(gè)不同的實(shí)例訪問(wèn)isolation。
在同步鎖機(jī)制中,后來(lái)者線程等待先行線程完成后,才能訪問(wèn)該成員變量。而ThreadLocal實(shí)現(xiàn)實(shí)例的復(fù)制而隔離對(duì)象訪問(wèn)數(shù)據(jù)沖突。同時(shí)也能夠少量解決scope為prototype訪問(wèn)模式下大量實(shí)例生命周期管理的消耗和負(fù)擔(dān)。是“以時(shí)間換空間”和“以空間換時(shí)間”的兩種實(shí)現(xiàn)。前者僅提供唯一變量,讓不同的線程排隊(duì)訪問(wèn),而后者為每一個(gè)線程都提供了一份拷貝,因此可以同時(shí)訪問(wèn)而互不影響,同時(shí)該拷貝存儲(chǔ)于內(nèi)存中,下次再次訪問(wèn)時(shí)候不再重新生成實(shí)例,減少服務(wù)器資源消耗。
我們知道在一般情況下,只有無(wú)狀態(tài)的Bean才可以在多線程環(huán)境下共享,在Spring中,絕大部分Bean都可以聲明為singleton作用域。就是因?yàn)镾pring對(duì)一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非線程安全狀態(tài)采用ThreadLocal進(jìn)行處理,讓它們也成為線程安全的狀態(tài),因?yàn)橛袪顟B(tài)的Bean就可以在多線程中共享了。
線程安全問(wèn)題:由全局變量及靜態(tài)變量引起,若每個(gè)線程中對(duì)全局變量、靜態(tài)變量只有讀操作,而無(wú)寫(xiě)操作,一般來(lái)說(shuō),這個(gè)全局變量是線程安全的;若有多個(gè)線程同時(shí)執(zhí)行寫(xiě)操作,一般都需要考慮線程同步,否則就可能影響線程安全。
1) 常量始終是線程安全的 (值恒定)
2)每次調(diào)用方法前都新建一個(gè)實(shí)例是線程安全的。(不同實(shí)例相互隔離)
3)局部變量是線程安全的(隔離)
因?yàn)槊繄?zhí)行一個(gè)方法,都會(huì)在獨(dú)立的空間創(chuàng)建局部變量,它不是共享的資源。局部變量包括方法的參數(shù)變量和方法內(nèi)變量。
有狀態(tài):有數(shù)據(jù)存儲(chǔ)、更改功能。有狀態(tài)對(duì)象(Stateful Bean),有實(shí)例變量的對(duì)象 ,可以保存數(shù)據(jù),是非線程安全的。
無(wú)狀態(tài):就是一次操作,不能變更數(shù)據(jù)。無(wú)狀態(tài)對(duì)象(Stateless Bean),沒(méi)有實(shí)例變量的對(duì)象,不能保存數(shù)據(jù),是不變類,是線程安全的。在spring中單例模式是共享實(shí)例,以達(dá)到提高性能。有狀態(tài)的Bean,多線程環(huán)境下不安全,那么適合用Prototype原型模式。Prototype: 每次對(duì)bean的請(qǐng)求都會(huì)創(chuàng)建一個(gè)新的bean實(shí)例。
如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Spring Security驗(yàn)證流程剖析及自定義驗(yàn)證方法
Spring Security是一個(gè)能夠?yàn)榛赟pring的企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問(wèn)控制解決方案的安全框架。這篇文章主要介紹了Spring Security驗(yàn)證流程剖析及自定義驗(yàn)證方法,需要的朋友可以參考下2018-03-03
Springboot 使用具體化類和配置來(lái)縮短單元測(cè)試時(shí)間
這篇文章主要介紹了Springboot 使用具體化類和配置來(lái)縮短單元測(cè)試時(shí)間,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Java數(shù)據(jù)結(jié)構(gòu)順序表用法詳解
順序表是計(jì)算機(jī)內(nèi)存中以數(shù)組的形式保存的線性表,線性表的順序存儲(chǔ)是指用一組地址連續(xù)的存儲(chǔ)單元依次存儲(chǔ)線性表中的各個(gè)元素、使得線性表中在邏輯結(jié)構(gòu)上相鄰的數(shù)據(jù)元素存儲(chǔ)在相鄰的物理存儲(chǔ)單元中,即通過(guò)數(shù)據(jù)元素物理存儲(chǔ)的相鄰關(guān)系來(lái)反映數(shù)據(jù)元素之間邏輯上的相鄰關(guān)系2021-10-10
Java8的default和static關(guān)鍵字的使用講解
今天小編就為大家分享一篇關(guān)于Java8的default和static關(guān)鍵字的使用講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01
SQL注入攻擊及其在SpringBoot中使用MyBatisPlus的防范策略的方法
本文介紹了如何使用SpringBoot整合JavaDeeplearning4j構(gòu)建一個(gè)文本摘要生成系統(tǒng),該系統(tǒng)能夠自動(dòng)從長(zhǎng)篇文本中提取關(guān)鍵信息,生成簡(jiǎn)潔的摘要,幫助用戶快速了解文本的主要內(nèi)容,系統(tǒng)使用LSTM神經(jīng)網(wǎng)絡(luò)模型進(jìn)行訓(xùn)練,并通過(guò)SpringBoot創(chuàng)建RESTful?API進(jìn)行調(diào)用2024-11-11
老生常談JVM的內(nèi)存溢出說(shuō)明及參數(shù)調(diào)整
下面小編就為大家?guī)?lái)一篇老生常談JVM的內(nèi)存溢出說(shuō)明及參數(shù)調(diào)整。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03
解決cmd運(yùn)行java程序“找不到文件”提示的方案
在本篇文章里小編給大家分享的是關(guān)于解決cmd運(yùn)行java程序“找不到文件”提示的方案,有需要的朋友們可以參考下。2020-02-02
java 驗(yàn)證用戶是否已經(jīng)登錄與實(shí)現(xiàn)自動(dòng)登錄方法詳解
本文主要介紹了java 驗(yàn)證用戶是否已經(jīng)登錄與實(shí)現(xiàn)自動(dòng)登錄的方法。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-01-01

