之前在Dubbo分布式日志中,当在子线程中使用ThreadContext或者MDC时候发现根本取不到值,是因为这两个都是ThreadLocal变量。其中ThreadLocal类有个子类InheritableThreadLocal它对ThreadLocal进了增强,当主线程变量用InheritableThreadLocal去包裹,后面子线程再通过get()方法获取主线程之前set的值发现能获取到,因为InheritableThreadLocal在初始化的时候会把之前主线程中设置了的值再复制一份。
具体可以参考:http://blog.csdn.net/ni357103403/article/details/51970748
下面是一个测试:
定义一个线程类:
public class MyThread extends Thread {
public void run() {
System.out.println(Thread.currentThread().getName() + ":" + MainClass.local.get());
}
}
主方法:
public class MainClass {
public static ThreadLocal<Integer> local = new InheritableThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return 0;
}
};
public static void main(String[] args) {
local.set(123);
System.out.println(Thread.currentThread().getName() + ":" + local.get());
Thread t1 = new MyThread();
Thread t2 = new MyThread();
t1.start();
t2.start();
}
}
当使用ThreadLocal:
public static ThreadLocal<Integer> local = new ThreadLocal<Integer>(){ ... }
测试结果如下:
当使用InheritableThreadLocal:
public static ThreadLocal<Integer> local = new InheritableThreadLocal<Integer>(){ ... }
测试结果如下:
当重写childValue方法时候,相当于子线程的值可以作为父线程值的一个任意函数。
如下(重写childValue方法):
public static ThreadLocal<Integer> local = new InheritableThreadLocal<Integer>() {
@Override
protected Integer childValue(Integer parentValue) {
return super.childValue(parentValue)+1;
}
@Override
protected Integer initialValue() {
return 0;
}
};
当子线程去get值值时候,结果如下: