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

2021-09-26 21:08:57 字數 1800 閱讀 5486

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

spring bean無可變的狀態(比如serview類和dao類)(也就是無狀態的bean  沒有執行緒公用的屬性也就是成員變數),執行緒安全

如果有狀態的bean也就是有屬性  那麼會導致執行緒不安全 可以將作用域由「singleton」變更為「prototype」

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框架 在Ioc容器中配置Bean

配置bean 配置形式 基於xml檔案的方式,基於註解的方式 bean的配置方式 通過全類名 反射 通過工廠方法 靜態工廠方法 例項工廠方法 factorybean 依賴注入的方式 屬性注入,構造器注入 注入屬性值細節 自動轉配 bean之間的關係 繼承 依賴 bean的作用域 singleton ...

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

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

spring 單例模式

單例模式,在spring 中其實是scope 作用範圍 引數的預設設定值 每個bean定義只生成乙個物件例項,每次getbean請求獲得的都是此例項 餓漢模式 spring singleton的預設是餓漢模式 啟動容器時 即例項化容器時 為所有spring配置檔案中定義的bean都生成乙個例項 懶漢...