spring的ThreadLocal解決線程安全


參考資料:https://www.bilibili.com/video/BV1Ki4y1t7Va?t=4507

1.spring項目在開發過程中用的都是數據庫連接池,這樣可以避免線程的消耗,

之前說過spring的事務問題,事務保證了操作的一致性,那么線程安全是怎么保證的呢?

 

 底層用的ThreadLocal來保證線程之間的數據隔離

當一個線程開啟事務時,會從連接池取一個連接 放到與自己綁定的ThreadLocal中,這個線程在service和dao層中獲取連接時直接從ThreadLocal中獲取,最后執行完了會把連接放回到線程池中。

源碼:查看spring事務管理的DataSourceTransactionManager類的doBegin方法。

 

 

然后

 

 點開resources,發現是一個ThreadLocal對象

 

再點發現這個NameThreadLocal類繼承自ThreadLocal,只是多了一個名字。

 

 這個類在spring中哪里用了呢?可以看到,spring中大量使用了ThreadLocal

 注:ThreadLocal是跟線程(通過線程id)綁定的,ThreadLocal是用來暫時存放數據的。

用法如下,在很多的登錄安全框架中就是用的ThreadLocal來保存用戶信息,如:security,因此在獲取用戶信息的時候才能獲取當前線程對應的ThreadLocal對應的用戶信息,

通過ThreadLocal來隔離用戶信息,ThreadLocla是每個線程的實例,因此每個線程的ThreadLocal內容都是不一樣的,spring通過ThreadLocal實現線程之間隔離,通過

單例模式來減少資源的消耗。

 在我的項目中,ThreadLocal和session是傳遞用戶信息的:

流程如下:

 

 

 

 

 配置過濾器,在過濾器中從session中獲取用戶信息,然后存到ThreadLocal中,所以同一個線程獲取的用戶信息是一樣的,因為session在同一客戶端也是一樣的,所以不同線程之前也能共享同一個用戶信息。

注意理解request請求,session,以及生命周期:

每一個request就是一個線程,在web項目中這些個線程都是由Tomcat線程池管理,一次請求結束后request的生命周期也就結束了,

要延長request的生命周期可以用forward,但是redirect不行。

而Session是整個會話期間,注意,不同客戶端的創建session的時候返回的JSESSIONID是不一樣的,這就說明session也是不一樣的,

session在服務器中是以session列表的形式存在的。

 


免責聲明!

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



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