InheritableThreadLocal
InheritableThreadLocal类继承于ThreadLocal类,所以它具有ThreadLocal类的特性,但又是一种特殊的 ThreadLocal,其特殊性在于InheritableThreadLocal变量值会自动传递给所有子线程,即在创建子线程时,子线程会接收所有可继承的线程局部变量的初始值,以获得父线程所具有的值。而普通ThreadLocal变量不行。
如果一个子线程调用InheritableThreadLocal的get(),那么它将与它的父线程看到同一个对象。为保护线程安全性,应该只对不可变对象(一旦创建,其状态就永远不会被改变的对象)使用InheritableThreadLocal,因为对象被多个线程共享。
public class InheritableThreadLocalTest { InheritableThreadLocal<StringBuilder> a = new InheritableThreadLocal<>(); InheritableThreadLocal<String> b = new InheritableThreadLocal<String>(); public static void main(String[] args) throws InterruptedException { final InheritableThreadLocalTest test = new InheritableThreadLocalTest(); test.a.set(new StringBuilder("main---hello")); test.b.set("main---zero"); System.out.println(test.a.get()); System.out.println(test.b.get()); Thread thread1 = new Thread() { public void run() { System.out.println(test.a.get()); System.out.println(test.b.get()); StringBuilder a = test.a.get().append("---subThread"); test.a.set(a); test.b.set("subThread--zero"); System.out.println(test.a.get()); System.out.println(test.b.get()); }; }; thread1.start(); thread1.join(); System.out.println(test.a.get()); System.out.println(test.b.get()); } }
main---hello main---zero main---hello main---zero main---hello---subThread subThread--zero main---hello---subThread main---zero
可以看出,如果InheritableThreadLocal存储的是可变性(mutable)的对象,如StringBuilder,对于主线程设置的值子线程可以通过get函数获取,但子线程调用set函数设置新值后,对主线程没有影响,对其它子线程也没有影响,只对自己可见,但如果子线程先get获取再修改对象的属性,那么这个修改对主线程和其它子线程是可见的,因为共享的是同一个引用。为了保护线程的安全性,一般建议只传递不可变(Immuable)对象,即没有状态的对象。
转自:https://blog.csdn.net/zero__007/article/details/50426286