使用ThreadLocal請務必remove


 

特別注意,web容器的線程是重復使用的,web容器使用了線程池,當一個請求使用完某個線程,該線程會放回線程池被其它請求使用,這就導致一個問題,不同的請求還是有可能會使用到同一個線程(只要請求數量大於線程數量),而ThreadLocal是屬於線程的,

如果我們使用完ThreadLocal對象而沒有手動刪掉,那么后面的請求就有機會使用到被使用過的ThreadLocal對象!

這時候分情況考慮了:

1此請求在使用ThreadLocal的時候,是先get()來判斷然后再set(),那就會有問題。因為get到的是別的請求set的內容,

2此請求在使用ThreadLocal,都是先set再get,那就不會有問題,因為一個線程同一時刻只被一個請求使用,只要我們每次使用之前,都設置成自己想要的內容,那就不會在使用的過程中被覆蓋。

使用ThreadLocal最好是每次使用完就調用remove方法,將其刪掉,避免先get后set的情況導致業務的錯誤。

 

第二點,不remove的話容易造成堆棧內存溢出。

 

線程池重用線程時,會對ThreadLocal的值進行清空嗎?

 

 

《Java並發編程實戰》一書的第8章時,有如下一句話:

 

只有當線程本地值的生命周期受限於任務的生命周期時,在線程池的線程中使用ThreadLocal才有意義,而在線程池的線程中不應該使用ThreadLocal在任務之間傳遞值。

 

------------

不會清空,要你自己去清空。

ask指的是一個Thread所執行的任務。

總之就是告訴你,如果你能夠在使用ThreadLocal的時候管理它的創建、銷毀,那么就可以用,否則會出問題。原因是ThreadLocal是和Thread綁定的,如果Thread是從Thread Pool中拿出來的,那么意味着Thread可能會被復用,如果被復用,你就一定得保證這個Thread上一次結束的時候,其關聯的ThreadLocal被清空掉,否則就會串到下一次使用。

 


免責聲明!

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



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