作用
当前线程创建子线程时,子线程能够继承父线程中的ThreadLocal变量;
public class Test {
static ThreadLocal<String> threadLocal = new InheritableThreadLocal<>();
// static ThreadLocal<String> threadLocal = new ThreadLocal<>();
public static void main(String[] args) {
// Parent Thread
threadLocal.set("AAA");
System.out.println("Parent Thread value is: " + threadLocal.get());
// Child Thread
new Thread(){
@Override
public void run() {
System.out.println("Child Thread value is: " + threadLocal.get());
}
}.start();
}
}
原理
在创建Thread实例时,将父线程的inheritableThreadLocals拷贝到当前线程的inheritableThreadLocals,如下代码所示:
childValue
根据父线程的值计算得到当前线程的值,如下所示:
private ThreadLocalMap(ThreadLocalMap parentMap) {
Entry[] parentTable = parentMap.table;
int len = parentTable.length;
setThreshold(len);
table = new Entry[len];
for (int j = 0; j < len; j++) {
Entry e = parentTable[j];
if (e != null) {
@SuppressWarnings("unchecked")
ThreadLocal<Object> key = (ThreadLocal<Object>) e.get();
if (key != null) {
Object value = key.childValue(e.value);
Entry c = new Entry(key, value);
int h = key.threadLocalHashCode & (len - 1);
while (table[h] != null)
h = nextIndex(h, len);
table[h] = c;
size++;
}
}
}
}
使用注意
JDK的InheritableThreadLocal类可以完成父线程到子线程的值传递。但对于使用线程池等会缓存线程的组件的情况,线程由线程池创建好,并且线程是缓存起来反复使用的;这时父子线程关系的ThreadLocal值传递已经没有意义,应用需要的实际上是把 任务提交给线程池时的ThreadLocal值传递到任务执行时。
参考: