ThreadLocal可能踩到的坑
背景
- 首先ThreadLocal 不做太多的介紹,在多執行緒場景下有著廣泛的應用。
- 最近在實現OneLog方法級日誌的時候,使用了 ThreadLocal 作為快取和計數器,在除錯過程中,發現有一些場景會出現資料錯亂和記憶體溢位的問題。
詳情
- OneLog方法級日誌使用 ThreadLocal 有兩個場景,一個是將方法入參資訊快取起來,然後在方法結束之後與返回結果進行組裝。另一個是作為計數器使用,保證迴圈方法的場景下,不會列印太多的日誌。
- 實際使用的時候發現了問題,ThreadLocal 物件的生命週期是依賴於執行緒的,那麼對於一個web應用來說,tomcat的執行緒是迴圈使用的,也就是說在web應用中,主執行緒下 ThreadLocal 物件永遠不會被回收!
- 下面是問題復現示例程式碼:
@Controller
public class TestThreadLocalController {
//計數器
private final ThreadLocal<Integer> counter = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return 0;
}
};
@RequestMapping("/testThreadLocal")
public @ResponseBody Integer testThreadLocal() {
doSomething();
return counter.get();
}
private void doSomething() {
counter.set(counter.get()+1);
}
}
- 執行多次web介面呼叫,當tomcat執行緒出現重複使用的時候,即可看到返回值大於1的情況:
解決方案
- 線上程池(包括web主執行緒)中使用 ThreadLocal 的時候,一定要考慮到 ThreadLocal 物件的生命週期是跟隨執行緒的,會隨著執行緒池的迴圈而一直存在。
-
那麼在這種場景下,使用 ThreadLocal 就要注意這幾點:
- Map、List、Set等集合物件,要考慮資料是否會一直增加,如果一直增加而不移除的話就會造成記憶體溢位。
- 用作計數器的話,使用之後要清0,不然計數的數值會隨著執行緒一直儲存下來。
相關文章
- 聊聊快取布林值踩到的坑快取
- MyBatis if 標籤的坑,居然被我踩到了。。。MyBatis
- 總結開發過程踩到的坑(一)
- 很高興!終於踩到了慢查詢的坑
- 聊聊使用@RefreshScope與nacos2整合踩到的坑
- 舒服了,學習了,踩到一個 Lombok 的坑!Lombok
- 關於這一次h5踩到的坑H5
- 說說最近工作中go語言踩到的坑Go
- vue websocket nodeJS 進行實時通訊踩到的坑VueWebNodeJS
- TinyRMI—RMI的封裝、擴充套件及踩到的坑的解決封裝套件
- 關於ThreadLocal變數的一個坑thread變數
- i/o timeout , 希望你不要踩到這個net/http包的坑HTTP
- 線上問題排查,一不小心踩到阿里的 arthas坑了阿里
- 使用laravels可能遇到的小小坑Laravel
- ThreadLocal原理記錄,別被坑了!!thread
- 可能有人聽過ThreadLocal,但一定沒人聽過ThreadLocal物件池thread物件
- 圓桌會議:如何避免踩到移動研發中,效能提升那些坑
- 記錄一下第一次安裝laradock踩到的各種坑
- AsyncTask可能有的坑-AndroidAndroid
- 最接地氣的一套PHP面試題(總結不易,踩坑踩到掛了好多面試)PHP面試題
- 記錄一下centos7.2 redhat7 安裝oracle11g我踩到的坑CentOSRedhatOracle
- Blazor Hybrid 實戰體驗:那些你可能沒預料到的坑沒預料到的坑Blazor
- 最接地氣的一套PHP面試題(完結)(總結不易,踩坑踩到掛了好多面試)PHP面試題
- ThreadLocal的使用thread
- 將GitLab.com折騰到Kubernetes的一年中,我們踩到了什麼坑?Gitlab
- ThreadLocal的介紹thread
- ThreadLocal的工作原理thread
- 記一次ThreadLocal引發的線上故障,年終獎沒了,可能還面臨辭退thread
- ThreadLocalthread
- ThreadLocal的簡單理解thread
- Threadlocal詳解(ThreadLocal,InheritTableThreadLocal,TransmittableThreadLocal)threadMIT
- 太極限了,JDK的這個BUG都能被我踩到JDK
- ThreadLocal分析thread
- ThreadLocal解析thread
- ThreadLocal理解thread
- 解析ThreadLocalthread
- ThreadLocal 剖析thread
- ThreadLocal 解析thread