Spring 是如何解決並發訪問的線程安全性問題的


  springmvc的controller是singleton的(非線程安全的),這也許就是他和struts2的區別吧!和Struts一樣,Spring的Controller默認是Singleton的,這意味着每個request過來,系統都會用原有的instance去處理,這樣導致了兩個結果:一是我們不用每次創建Controller,二是減少了對象創建和垃圾收集的時間;由於只有一個Controller的instance,當多個線程調用它的時候,它里面的instance變量就不是線程安全的了,會發生竄數據的問題。當然大多數情況下,我們根本不需要考慮線程安全的問題,比如dao,service等,除非在bean中聲明了實例變量。因此,我們在使用spring mvc 的contrller時,應避免在controller中定義實例變量。 

 

       如果控制器是使用單例形式,且controller中有一個私有的變量a,所有請求到同一個controller時,使用的a變量是共用的,即若是某個請求中修改了這個變量a,則,在別的請求中能夠讀到這個修改的內容。。

有幾種解決方法:
1、在Controller中使用ThreadLocal變量
2、在spring配置文件Controller中聲明 scope="prototype",每次都創建新的controller

所在在使用spring開發web 時要注意,默認Controller、Dao、Service都是單例的。

 

ThreadLocal 使用范例:

 ThreadLocal<Long>startTime = newThreadLocal<Long>();  定義一個ThreadLocal 變量

startTime.set(System.currentTimeMillis());   寫入值

startTime.get();  讀取值

 

 

ThreadLocal和線程同步機制相比有什么優勢呢?

ThreadLocal和線程同步機制都是為了解決多線程中相同變量的訪問沖突問題。

在同步機制中,通過對象的鎖機制保證同一時間只有一個線程訪問變量。這時該變量是多個線程共享的,使用同步機制要求程序慎密地分析什么時候對變量進行讀寫,什么時候需要鎖定某個對象,什么時候釋放對象鎖等繁雜的問題,程序設計和編寫難度相對較大。

而ThreadLocal則從另一個角度來解決多線程的並發訪問。ThreadLocal會為每一個線程提供一個獨立的變量副本,從而隔離了多個線程對數據的訪問沖突。因為每一個線程都擁有自己的變量副本,從而也就沒有必要對該變量進行同步了。ThreadLocal提供了線程安全的共享對象,在編寫多線程代碼時,可以把不安全的變量封裝進ThreadLocal。

概括起來說,對於多線程資源共享的問題,同步機制采用了“以時間換空間”的方式,而ThreadLocal采用了“以空間換時間”的方式。前者僅提供一份變量,讓不同的線程排隊訪問,而后者為每一個線程都提供了一份變量,因此可以同時訪問而互不影響。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM