一、發(fā)現(xiàn)問題
使用場景: 攔截器賦值(ThreadLocal.set),不依賴上下文傳參,同一個線程內(nèi)傳值(ThreadLocal.get)
使用現(xiàn)象: 在父線程ThreadLocal.set,子線程get不到值。
private final static ThreadLocal<String> threadLocal = new ThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
threadLocal.set("MainSet");
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(() -> {
System.out.println(Thread.currentThread().getName() + " get => " + threadLocal.get());
});
Thread.sleep(1000);
executorService.shutdown();
System.out.println("Main - end");
// out =>
// pool-1-thread-1 get => null
// Main - end
}
二、解決方案
- 傳參傳進子線程。
- 使用InheritableThreadLocal。
三、ThreadLocal介紹
作用: 線程隔離、線程獨享
看源碼: threadLocal.set/threadLocal.get

image.png
看著像threadLocal1.set、threadLocal2.set,
實際是Thread.currentThread().ThreadLocalMap.set(ThreadLocal threadLocal1, Object value)、 Thread.currentThread().ThreadLocalMap.set(ThreadLocal threadLocal2, Object value)

image.png
實現(xiàn)線程隔離

image.png
四、為什么InheritableThreadLocal可以實現(xiàn)子線程傳遞
看源碼...InheritableThreadLocal

image.png
由此可見,只是copy,并不共享,copy之后還是隔離
驗證....
五、應(yīng)用場景
- 攔截器,獲取上下文。
- PageHelper。
優(yōu)點: 減少代碼侵入
缺點: 不易維護
六、下期講解
- 內(nèi)部Map結(jié)構(gòu)、解決hash沖突方式、與jdkHashMap、redis-hash的比較。
- 弱引用、弱引用導(dǎo)致的內(nèi)存泄漏。