一、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;)
来源:oschina
链接:https://my.oschina.net/u/4412486/blog/3232670