Spring中的Bean是線程安全的嗎?為什么?

Spring中的Bean是線程安全的嗎?為什么?

????????答案:不是。


????????因為SpringIOC容器本身沒有提供Bean的線程安全策略,所以Spring容器中的Bean本身不具備線程安全的特性,現(xiàn)在結合具體的作用域(scope)去研究。


Spring的Bean作用域scope類型(五種):

? ? ? ? a.singleton(單例):默認作用域,SpringIOC中僅存在一個Bean實例,以單例Bean的方式存在。

? ? ? ? b.prototype(原型):每次從容器中getBean()時,都返回一個新的實例。等于執(zhí)行new Bean()。

? ? ? ? c.request(請求):每次Http請求創(chuàng)建一個新對象。

? ? ? ? d.session(會話):同一個會話共享一個實例,不同會話使用不同實例。

? ? ? ? e.global-session(全局會話):所有會話共享一個實例。

request(請求)、session(會話)、global-session(全局會話):

? ??????**\color{red}{僅僅適用于WebApplicationContext環(huán)境下。}**

????????$\color{red}{紅色字}$

線程安全這個問題,從常用的單例和原型Bean分別說明:

singleton(單例)Bean:

? ? ? ? 所有線程都共享一個單例Bean,因此是存在資源的競爭。

? ? ? ? 如果單例Bean是無狀態(tài)的,也就是線程之間的操作不會對Bean的成員執(zhí)行查詢以外的操作,那么這個單例Bean是線程安全的。比如:Spring Mvc、Controller、Service、Dao等,這些Bean大多數(shù)是無狀態(tài)的,只需要關注方法本身即可。

prototype(原型)Bean:

????????每個線程都創(chuàng)建一個新的對象,線程之間不存在Bean的共享,自然不存在線程安全的問題。

Spring中Bean是默認單例的,為什么Controller、Service、和Dao能保證線程安全?

? ? ? ? Spring 中Bean默認是單例模式的,框架并沒有對Bean進行多線程的封裝處理。? ? ? ?

? ? ? ? Controller、Service和Dao本身并不是線程安全的,Java虛擬機棧是線程私有的,它的生命周期與線程相同,跟隨線程結束而結束。

? ? ? ? 但是,如果Bean是有狀態(tài)的,就需要開發(fā)人員自己來進行線程安全的保證,最簡單的方法就是改變Bean的作用域把“singleton”改為“prototype",這樣每次請求Bean都相當于new Bean(),問題解決。


tips:

? ? ? ? 有狀態(tài)就是有存儲數(shù)據(jù)的功能。

? ? ? ? 無狀態(tài)就是不會存儲數(shù)據(jù)。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
禁止轉載,如需轉載請通過簡信或評論聯(lián)系作者。

友情鏈接更多精彩內容