前言
ThreadLocal是相对于每一个线程自己使用的本地变量,有这样的一种需求:父线程生成的变量需要传递到子线程中进行使用。需要使用新的InheritableThreadLocal类来实现,但
InheritableThreadLocal的使用利用Thread 的初始化。我们经常在使用线程的时候,都是使用线程池的方式这个时候就需要TransmittableThreadLocal登场来解决。
实践
一、InheritableThreadLocal使用
public class LocalThreadUtil {
private static ThreadLocal<String> threadLocal = new ThreadLocal<>();
private static InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();
public static void main(String[] args) {
threadLocal.set("mian threadLocal");
inheritableThreadLocal.set("mian inheritableThreadLocal");
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("threadLocal is data is =====" + threadLocal.get());
System.out.println("inheritableThreadLocal is data is =====" + inheritableThreadLocal.get());
}
}).start();
}
}
线程输出:
threadLocal is data is =====null
inheritableThreadLocal is data is =====mian inheritableThreadLocal
可以看到inheritableThreadLocal 在子线程中能够获取到父线程的设置的值,我们可以探究一下这个如何做到的。
原理:
public class InheritableThreadLocal<T> extends ThreadLocal<T> {
//这个是在初始化 thread 中的InheritableThreadLocal 成员变量初始化获取中根据父类值
//获取子类的值,返回和父类一摸一样所以有了地址拷贝
protected T childValue(T parentValue) {
return parentValue;
}
//threadLocal 中的 ThreadLocalMap getMap(Thread t) {return t.threadLocals;}
//是调用线程t.threadLocals; 那说明使用 inheritableThreadLocal 对inheritableThreadLocals 进行初始化操作
ThreadLocalMap getMap(Thread t) {
return t.inheritableThreadLocals;
}
void createMap(Thread t, T firstValue) {
t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
}
}
可以看到InheritableThreadLocal是借助父类的ThreadLocal的能力,继承自ThreadLocal,并且重写了父类的方法:createMap(),getMap(),childValue();Thread 中有两个ThreadLocal和InheritableThreadLocal成员变量,数据类型都是ThreadLocal.ThreadLocalMap 当我们new Thread 新线程调用初始化,操作了成员变量
ThreadLocal 和 InheritableThreadLocal
ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal