多线程之子线程共享父线程的ThreadLocal:InheritableThreadLocal
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();
}
}
原文链接:https://blog.youkuaiyun.com/lnktoking/article/details/80362111