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

posted @ 2018-09-19 15:45  ZECDLLG  阅读(152)  评论(0编辑  收藏  举报