InheritableThreadLocal-实现线程共享数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了InheritableThreadLocal-实现线程共享数据相关的知识,希望对你有一定的参考价值。

参考技术A 在之前开发项目的时候遇到的一个场景:

servlet线程和业务线程是两个独立的线程,以及业务处理过程中如果创建其他异步线程也是独立的线程;线程之间参数传递完全可以通过参数传递的方式,这样我在程序开发的时候就反复地传递最初创建的对象bean即可;这种方式会造成相当大的代码冗余;

于是,想到将记录集中在一个地方处理。

愿意翻源码的筒子们可以去翻源码,这里直接说原因,ThreadLocal是一个线程局部变量,在统一线程中使用没有问题,但在上述场景中发生了线程切换,完全不能实现业务目的;

比如在独立的当前线程处理时:

但是当发生线程切换时,子线程已经获取不到父级线程中创建的内容了:

替换成InheritableThreadLocal后

多个子线程中都可以获取到对象了。问题解决!

Java多线程-ThreadLocal和InheritableThreadLocal的使用

ThreadLocal类

变量值的共享可以通过使用public static变量的形式。如果想每个线程都有自己的共享变量,可以通过JDK提供的ThreadLocal来实现。

类 ThreadLocal 主要解决的就是每个线程绑定自己的值,可以将 ThreadLocal 类比喻成全局存放数据的盒子,盒子中可以存放每个线程的私有变量。

示例:

public class Test {
    public static void main(String[] args) {
        try {
            for (int i = 0; i < 5; i++) {
                System.out.println("   在 Main 线程中取值 = " + ThreadLocalHolder.getInstance().get());
                Thread.sleep(500);
            }
            Thread.sleep(2500);
            ThreadA a = new ThreadA();
            a.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class ThreadA extends Thread {
        @Override
        public void run() {
            try {
                for (int i = 0; i < 5; i++) {
                    System.out.println("在 ThreadA 线程中取值 = " + ThreadLocalHolder.getInstance().get());
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class ThreadLocalHolder {
        private ThreadLocalHolder() {
        }

        public static ThreadLocal getInstance() {
            return ThreadLocalHolder.Holder.INSTANCE;
        }

        private static class Holder {
            static final ThreadLocalHolder.MyThreadLocal INSTANCE = new ThreadLocalHolder.MyThreadLocal();
        }

        /**
         * 集成 ThreadLocal,给每个线程的共享变量一个初始值
         */
        private static class MyThreadLocal extends ThreadLocal {
            @Override
            protected Object initialValue() {
                return System.currentTimeMillis();
            }
        }
    }
}

运行结果如图:

 

 

类InheritableThreaddLocal 的使用

使用类 InheritableThreadLocal 可以在子线程中取得父线程继承下来的值。

示例:

public class Test {
    public static void main(String[] args) {
        try {
            for (int i = 0; i < 5; i++) {
                System.out.println("   在 Main 线程中取值 = " + ThreadLocalHolder.getInstance().get());
                Thread.sleep(500);
            }
            Thread.sleep(2500);
            ThreadA a = new ThreadA();
            a.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class ThreadA extends Thread {
        @Override
        public void run() {
            try {
                for (int i = 0; i < 5; i++) {
                    System.out.println("在 ThreadA 线程中取值 = " + ThreadLocalHolder.getInstance().get());
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class ThreadLocalHolder {
        private ThreadLocalHolder() {
        }

        public static InheritableThreadLocal getInstance() {
            return ThreadLocalHolder.Holder.INSTANCE;
        }

        private static class Holder {
            static final ThreadLocalHolder.MyInheritableThreadLocal INSTANCE = new ThreadLocalHolder.MyInheritableThreadLocal();
        }

        /**
         * 集成 InheritableThreadLocal,给每个线程的共享变量一个初始值
         */
        private static class MyInheritableThreadLocal extends InheritableThreadLocal {
            @Override
            protected Object initialValue() {
                return System.currentTimeMillis();
            }
        }
    }
}

运行结果如下:

 

以上是关于InheritableThreadLocal-实现线程共享数据的主要内容,如果未能解决你的问题,请参考以下文章

ThreadLoacl,InheritableThreadLocal,原理,以及配合线程池使用的一些坑

Java多线程-ThreadLocal和InheritableThreadLocal的使用

InheritableThreadLocal原理

InheritableThreadLocal详解

多线程-InheritableThreadLocal

InheritableThreadLocal原理解析