一、前言
ThreadLocal是JDK里面提供的一个thread-local(线程局部)的变量,当一个变量被声明为ThreadLocal时候,每个线程会持有该变量的一个独有副本;但是ThreadLocal不支持继承性,虽然JDK里面提供了InheritableThreadLocal来解决继承性问题,但是其也是不彻底的,本节我们谈谈增强的TransmittableThreadLocal,其可以很好解决线程池情况下继承问题。
二、TransmittableThreadLocal
前面说了,当一个变量被声明为ThreadLocal时候,每个线程会持有该变量的一个独有副本,比如下面例子:
private static ThreadLocal<String> parent = new ThreadLocal<String>();
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
try {
// 设置本线程变量
parent.set(Thread.currentThread().getName() + "hello,jiaduo");
// dosomething
Thread.sleep(3000);
// 使用线程变量
System.out.println(Thread.currentThread().getName() + ":" + parent.get());
// 清除
parent.remove();
// do other thing
//.....
} catch (Exception e) {
e.printStackTrace();
}
}, "thread-1").start();
new Thread(() -> {
try {
// 设置本线程变量
parent.set(Thread.currentThread().getName() + "hello,jiaduo");
// dosomething
Thread.sleep(3000);
// 使用线程变量
System.out.println(Thread.currentThread().getName() + ":" + parent.get());
// 清除
parent.remove();
// do other thing
//.....
} catch (Exception e) {
e.printStackTrace();
}
}, "thread-2").start();
}
如上代码线程1和线程2各自持有parent变量中的副本,其相互之间并发访问自己的副本变量,不会存在线程安全问题。
但是ThreadLocal不支持继承性:
public static void main(String[] args) throws InterruptedException {
T