Spring原始碼解析-7、spring容器中的Bean是否執行緒安全?
Spring容器中的Bean是否執行緒安全,容器本身並沒有提供Bean的執行緒安全策略,因此可以說spring容器中的Bean本身不具備執行緒安全的特性,但是具體還是要結合具體scope的Bean去研究。
spring 的 bean 有哪些scope[作用域]
1、singleton:單例。【預設】
2、prototype:原型,每次建立一個新物件
3、request:請求,每次Http請求建立一個新物件,適用於WebApplicationContext環境下。
4、session:會話,同一個會話共享一個例項。不同會話使用不用的例項。
5、global-session:全域性會話,所有會話共享一個例項。
從單例與原型Bean,去說執行緒安全
對於原型Bean,每次建立一個新物件,也就是執行緒之間並不存在Bean共享,自然是不會有執行緒安全的問題。
對於單例Bean,所有執行緒都共享一個單例例項Bean,因此是存在資源的競爭。
如果單例Bean,是一個無狀態Bean,也就是執行緒中的操作不會對Bean的成員執行查詢以外的操作,那麼這個單例Bean是執行緒安全的。
比如spring mvc 的 Controller、Service、Dao等,這些Bean大多是無狀態的,只關注於方法本身。
對於有狀態的bean,spring官方提供的bean,一般提供了通過ThreadLocal去解決執行緒安全的方法。
比如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等。
使用ThreadLocal的好處是使得多執行緒場景下,多個執行緒對這個單例Bean的成員變數並不存在資源的競爭,因為ThreadLocal為每個執行緒儲存執行緒私有的資料。這是一種以空間換時間的方式。
當然也可以通過加鎖的方法來解決執行緒安全,這種以時間換空間的場景在高併發場景下顯然是不實際的。