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,原理,以及配合线程池使用的一些坑