ThreadLocal的使用以及坑

參考:https://www.cnblogs.com/yxysuanfa/p/7125761.html

 

做個總結:

1.正常情況:

ThreadLocal<T> threadLocal = new ThreadLocal<>(),ThreadLocal 的構造函數接收的是一個泛型對象,可以是存儲一個String,Map,Entity等對象,我們通過操作 threadLocal.set(t), threadLocal.get(), threadLocal.remove()方法,可以在線程內部維護一個對象,用來在整個線程的生命週期中作爲數據總線傳遞參數。每個線程中存儲的數據都是隔離的。其原理是:threadLocal.set(t)時,會將 ThreadLocal 對象本身 this 作爲key(之所以用當前的 ThreadLocal 對象作爲key,是因爲一個線程執行的生命週期中,允許你創建很多的ThreadLocal對象,如ThreadLocal<會員信息對象>, ThreadLocal<訂單詳情對象>, ThreadLocal<產品詳情對象>),泛型對象 t 作爲 value 存儲在 ThreadLocal.ThreadLocalMap 對象中,而 ThreadLocal.ThreadLocalMap 對象又是當前執行的線程對象 Thread 的一個成員屬性,如此就保證了每個 ThreadLocal 中存儲的數據都是基於線程隔離的。

2.需要注意有那些坑:

既然我們明白了 ThreadLocal.ThreadLocalMap 是當前執行的線程對象的成員屬性,就應該知道其生命週期是和線程同步的。正常情況下,線程執行結束後出棧,等待被gc回收,生命週期正常結束是沒有問題的。但需要注意的是:在線程池中,線程執行結束後如果不被釋放,它的生命週期可能很長,會繼續等待下一次執行任務。而使用 ThreadLocal 存儲的泛型對象則會被線程在下一次執行時獲取到裏面的內容,此時存儲的數據相當於是線程共享的。解決辦法(最佳實踐)是:無論何時,使用 ThreadLocal 傳遞參數都要有始有終,在線程執行結束時,手動調用 threadLocal.remove() 方法,刪除 threadLocal.set(t) 時存放的數據,保證線程存儲的數據是安全的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章