多线程之子线程共享父线程的ThreadLocal:InheritableThreadLocal

多线程之子线程共享父线程的ThreadLocal:InheritableThreadLocal

 
ThreadLocal 相当于是线程的一个局部静态对象,它的值的作用域是当前整个线程,别的线程是无法获取到的它的值。如果子线程想获取到父线程的ThreadLocal的值该怎么办呢?这时候可以用 InheritableThreadLocal,InheritableThreadLocal的作用就是为了解决子线程想获取到父线程的ThreadLocal的值。

使用 InheritableThreadLocal 时有一点要注意的是,InheritableThreadLocal 的实现原理是在子线程创建的时候把主线程的 InheritableThreadLocal 值的内容的引用 copy 了一份给自己用,因为是 copy 出来的,所以创建子线程之后,子线程和主线程的 InheritableThreadLocal 是相互独立的了,它们之间怎么改 InheritableThreadLocal 的值也不会同步到对方的 InheritableThreadLocal 。

InheritableThreadLocal 的使用示例

public class InheritableThreadLocalTest {
    private static final ThreadLocal<String> threadLocal = new ThreadLocal<>();
    private static final InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();

    /**
     * 主线程
     */
    public static class MainThread extends Thread {
        @Override
        public void run() {
            try {
                //在主线程给 ThreadLocal 和 InheritableThreadLocal 设值
                String value = "hello world";
                System.out.println("主线程设置ThreadLocal的值为 " + value);
                threadLocal.set(value);
                inheritableThreadLocal.set(value);

                /*
                 * 在主线程创建子线程,这时候子线程会把主线程的InheritableThreadLocal的内容copy一份给自己用,
                 * 因为InheritableThreadLocal的内容是copy出来,所以当主线程改变了InheritableThreadLocal的
                 * 内容,子线程的内容不同步改变。同样,子线程改变了InheritableThreadLocal的内容,主线程的内容
                 * 不会同步改变。所以从子线程创建之后,两个线程的InheritableThreadLocal是独立的了。
                 */
                ChildThread childThread = new ChildThread();
                childThread.start();

                Thread.sleep(1000);
                System.out.println();

                //子线程创建之后再改变InheritableThreadLocal的值,子线程是不会影响的。
                value = "changed";
                System.out.println("主线程设置ThreadLocal的值为 " + value);
                threadLocal.set(value);
                inheritableThreadLocal.set(value);

                Thread.sleep(1000);
                //子线程改变了InheritableThreadLocal的值,主线程一样也不会影响。
                System.out.println();
                System.out.println("在主线程获取ThreadLocal的值:" + threadLocal.get());
                System.out.println("在主线程获取InheritableThreadLocal的值:" + inheritableThreadLocal.get());

                childThread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 子线程
     */
    public static class ChildThread extends Thread {

        @Override
        public void run() {
            try {
                //获取ThreadLocal的值
                getThreadLocal();
                Thread.sleep(1500);

                //在主线程修改了ThreadLocal的值之后再获取值,会获取到原来没修改之前的值
                System.out.println("子线程获取重设之后的值 ---");
                getThreadLocal();

                //在子线程修改ThreadLocal的值再让主线程获取,同样主线程也会获取不到子线和改后的值
                System.out.println();
                String value = "I'm still a kid.";
                System.out.println("在子线程设置ThreadLocal的值为:" + value);
                threadLocal.set(value);
                inheritableThreadLocal.set(value);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public void getThreadLocal(){
            System.out.println("在子线程中获取ThreadLocal的值:" + threadLocal.get());
            System.out.println("在子线程中获取InheritableThreadLocal的值:" + inheritableThreadLocal.get());
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new MainThread().start();
    }
}
 
原文链接:https://blog.csdn.net/lnktoking/article/details/80362111

猜你喜欢

转载自blog.csdn.net/zxl2016/article/details/105784214