![](/img/trans.png)
[英]Will the ThreadLocal object be cleared after thread returned to Thread Pool?
[英]ThreadLocal value not cleared for the next thread in java
我正在運行 web 服務,該服務至少接收 200 RPS。 基於該操作,我們為少數操作提供 root 訪問權限,並使用以下代碼。
private static final ThreadLocal<String> rootContext = new ThreadLocal<String>();
public Optional<String> getRunner() {
if (rootContext.get() != null) {
return rootContext.get();
} else {
return getCurrentRunner();
}
}
public void rootAccess(Runnable runnable) {
rootContext.set("root");
runnable.run();
rootContext.set(null);
}
getCurrentRunner()
方法將根據請求返回實際的調用者。 問題是 200 個請求中有 1 個返回root
而不是實際的調用者。
我注意到的一件事是,我沒有使用 threadlocal.remove(),而是將該值設置為 null。 預計 getRunner() rootContext.get() != null
條件將失敗並返回實際的調用者。
如何解決這個問題? 設置rootContext.remove()
會解決這個問題嗎? 如果是,如何?
謝謝您的幫助
您的rootAccess
方法有兩個問題:
rootContext.set(null);
仍然保持與正在運行的線程關聯的ThreadLocal
實例,最好做rootContext.remove();
更正這兩點意味着將rootAccess()
更改為
public void rootAccess(Runnable runnable) {
rootContext.set("root");
try {
runnable.run();
} finally {
rootContext.remove();
}
}
為什么是rootContext.set(null);
一般有問題嗎?
每個線程基本上都保留一個類似於Map<ThreadLocal, ?>
的數據結構,其中鍵是您的ThreadLocal
實例( rootContext
),值是您通過rootContext.set(xx);
如果你調用rootContext.set(null);
那么rootContext
仍然在 map 中,因此執行此行的每個線程(來自線程池,意味着線程長時間運行)都會保留對 rootContext 的引用,這反過來可能會阻止rootContext
卸載。
如果你調用rootContext.remove();
rootContext 從rootContext
中刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.