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(); } }