Spring單例Beans執行緒安全與否及解決方法

2021-10-08 20:14:55 字數 1564 閱讀 5706

看到這樣乙個問題:spring框架中的單例beans是執行緒安全的麼?

spring框架並沒有對單例bean進行任何多執行緒的封裝處理。關於單例bean的執行緒安全和併發問題需要開發者自行去搞定。但實際上,大部分的spring bean並沒有可變的狀態(比如serview類和dao類),所以在某種程度上說spring的單例bean是執行緒安全的。如果你的bean有多種狀態的話(比如 view model 物件),就需要自行保證執行緒安全。

最淺顯的解決辦法就是將多型bean的作用域由「singleton」變更為「prototype」。

在spring的bean配置中,存在這樣兩種情況:

當然,scope的值不止這兩種,還包括了request,session 等。但用的最多的還是singleton單態,prototype多型。

singleton表示該bean全域性只有乙個例項,spring中bean的scope預設也是singleton.

prototype表示該bean在每次被注入的時候,都要重新建立乙個例項,這種情況適用於有狀態的bean.

對於ssh架構的系統,很少關心這方面,因為我們用到的一般都是singleton. bean的注入由spring管理。

對於有狀態的bean呢?

下面是乙個有狀態的bean

package com.sw;  

public class testmanagerimpl implements testmanager

public void preparedata(user e) throws exception

}

如果該bean配置為singleton,會出現什麼樣的狀況呢?

如果有2個使用者訪問,都呼叫到了該bean.

假定為user1,user2

當user1 呼叫到程式中的1步驟的時候,該bean的私有變數user被付值為user1

當user1的程式走到2步驟的時候,該bean的私有變數user被重新付值為user1_create

理想的狀況,當user1走到3步驟的時候,私有變數user應該為user1_create;

但如果在user1呼叫到3步驟之前,user2開始執行到了1步驟了,由於單態的資源共享,則私有變數user被修改為user2

這種情況下,user1的步驟3用到的user.getid()實際用到是user2的物件。

而如果是prototype的話,就不會出現資源共享的問題。

對於ssh來說,bean的配置是沒錯的,配置為singleton ;實際應該是這個例子不應該用私有變數。這樣就使得這個bean

由無狀態變成了有狀態bean.還是應該盡量使用無狀態bean.如果在程式**現私有變數,盡量替換為引數。

對於每個訪問私有變數的方法增加變數傳入或者通過threadlocal來獲取也是不錯的方法。

真正出現上面**問題的也是少數,出現的時候,一般是為了圖方便,乙個很多方法都要用到的變數,如果都需要用引數的

方式傳遞多麻煩呀,這樣私有變數多好,不用引數那樣醜陋。但是醜陋並不代表不好,以對的,自己習慣的方式程式設計,才能

盡量避免問題的發生。

Spring框架中的單例Beans是執行緒安全的麼?

spring 框架並沒有對單例 bean 進行任何多執行緒的封裝處理。關於單例 bean 的執行緒安全和併發問題需要開發者自行去搞定。但實際上,大部分的 spring bean 並沒有可變的狀態 比如 serview 類和dao類 所以在某種程度上說 spring 的單例bean 是執行緒安全的。如...

spring框架中的單例Beans是執行緒安全的麼?

看到這樣乙個問題 spring框架中的單例beans是執行緒安全的麼?spring bean無可變的狀態 比如serview類和dao類 也就是無狀態的bean 沒有執行緒公用的屬性也就是成員變數 執行緒安全 如果有狀態的bean也就是有屬性 那麼會導致執行緒不安全 可以將作用域由 singleto...

Spring單例與執行緒安全小結

一 spring單例模式與執行緒安全 spring框架裡的bean,或者說元件,獲取例項的時候都是預設的單例模式,這是在多執行緒開發的時候要尤其注意的地方。二 執行緒安全案例 dateformat 下面簡稱sdf 類內部有乙個calendar物件引用,它用來儲存和這個sdf相關的日期資訊,例如sdf...