一、java子线程中获取父线程的threadLocal中的值
threadLocal可以做线程级的数据隔离,那如何在子线程中获取父线程的值呢? 可以使用InheritableThreadLocal
/** * Java子线程获取父线程的threadLocal中的值 */ public class ThreadDemo1 { public static final InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>(); public static final ThreadLocal<String> threadLocal = new ThreadLocal<>(); public static void main(String[] args) throws Exception { inheritableThreadLocal.set("inheritableThreadLocal hello"); threadLocal.set("threadLocal world"); new Thread(()->{ System.out.println(String.format("子线程可继承值:%s", inheritableThreadLocal.get())); System.out.println(String.format("子线程值:%s", threadLocal.get())); new Thread(()->{ System.out.println(String.format("孙线程可继承值:%s", inheritableThreadLocal.get())); System.out.println(String.format("孙线程值:%s", threadLocal.get())); }).start(); }).start(); Thread.sleep(3000); System.out.println("--------------修改可继承值threadLocal和threadLocal的值--------------------"); inheritableThreadLocal.set("inheritableThreadLocal hello2"); threadLocal.set("threadLocal world2"); new Thread(()->{ System.out.println(String.format("子线程可继承值:%s", inheritableThreadLocal.get())); System.out.println(String.format("子线程值:%s", threadLocal.get())); new Thread(()->{ System.out.println(String.format("孙线程可继承值:%s", inheritableThreadLocal.get())); System.out.println(String.format("孙线程值:%s", threadLocal.get())); }).start(); }).start(); } }
输出结果如下:
子线程可继承值:inheritableThreadLocal hello 子线程值:null 孙线程可继承值:inheritableThreadLocal hello 孙线程值:null --------------修改可继承值threadLocal和threadLocal的值-------------------- 子线程可继承值:inheritableThreadLocal hello2 子线程值:null 孙线程可继承值:inheritableThreadLocal hello2 孙线程值:null
说明在子线程和孙线程中可以获取到父线程的 inheritableThreadLocal 的值。修改inheritableThreadLocal 的值后,子线程和孙线程中同样可以获取到父线程的inheritableThreadLocal 的值。
但是threadLocal却不行,获取到的值为空。
2、查看创建Thread的源码
private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals) { ...... if (inheritThreadLocals && parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); /* Stash the specified stack size in case the VM cares */ this.stackSize = stackSize; /* Set thread ID */ tid = nextThreadID(); } //ThreadLocal.createInheritedMap static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) { return new ThreadLocalMap(parentMap); }
可以看到,创建线程时,调用了init方法,然后将父线程的inheritableThreadLocals赋值inheritableThreadLocals (ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;)