不要將ThreadLocal翻譯為線程本地化或本地線程,英語的解釋為 CopyValueIntoEveryThread
Thread的三個重要方法
1. set():如果沒有set操作的ThreadLocal,容易引起臟數據問題。
2. get():始終沒有get操作的ThreadLocal對象是沒有意義的。
3. remove():如果沒有remove操作,容易引起內存泄漏。
ThreadLocal的副作用:
* 臟數據 (由于沒有remove清理操作,在高并發的場景下,線程池中的線程可能會讀取到上一個線程緩存的信息)
* 內存泄漏
下面這段代碼就模擬了臟數據的產生:
public class DirtyDataInThreadLocal {
public static ThreadLocal<String> threadLocal = new ThreadLocal<String>();
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(1);
for (int i = 0; i < 2; i++) {
Mythread thread = new Mythread();
pool.execute(thread);
}
}
private static class Mythread extends Thread {
private static boolean flag = true;
@Override
public void run() {
if (flag) {
threadLocal.set(this.getName() + ", session info");
flag = false;
}
System.out.println(this.getName() + " 線程是 " + threadLocal.get());
}
}
}
以上兩個問題的解決辦法很簡單,每次用完ThreadLocal時,必須要及時調用remove()方法進行清理。