子线程如何获取父线程ThreadLocal的值

不卖关子,用InheritableThreadLocal
关于ThreadLocal可以参考我的另一篇文章
ThreadLocal使用及原理_编程还未的博客-优快云博客

ThreadLocal实战源码在文末。

1.使用

直接上代码。

public class InheritableThreadLocalTest1 {

    public static void main(String[] args) {
        ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
        threadLocal.set(1);
        InheritableThreadLocal<Integer> inheritableThreadLocal = new InheritableThreadLocal<>();
        inheritableThreadLocal.set(2);
        new Thread(() -> {
            System.out.println("threadLocal=" + threadLocal.get());
            //debug到这一行看源码
            System.out.println("inheritableThreadLocal=" + inheritableThreadLocal.get());
        }).start();
    }
}

运行结果

threadLocal=null
inheritableThreadLocal=2

2.原理

Thread类里面有两个ThreadLocal对象,一个是threadLocals(ThreadLocal对象),一个是inheritableThreadLocals(InheritableThreadLocal对象)。

    /* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;

    /*
     * InheritableThreadLocal values pertaining to this thread. This map is
     * maintained by the InheritableThreadLocal class.
     */
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

默认的new Thread()会获取parent线程的inheritableThreadLocals,并赋值。

public Thread(Runnable target) {
        this(null, target, "Thread-" + nextThreadNum(), 0);
}
public Thread(ThreadGroup group, Runnable target, String name,
                  long stackSize) {
       this(group, target, name, stackSize, null, true);
}
/**
*精简后的代码
*/
private Thread(ThreadGroup g, Runnable target, String name,
                   long stackSize, AccessControlContext acc,
                   boolean inheritThreadLocals) {

        Thread parent = currentThread();
       
        if (inheritThreadLocals && parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
 
    }

InheritableThreadLocal本身也比较简单。主要是getMap()、createMap()的时候操作的是Thread的inheritableThreadLocals

public class InheritableThreadLocal<T> extends ThreadLocal<T> {
 
    public InheritableThreadLocal() {}

    protected T childValue(T parentValue) {
        return parentValue;
    }

    ThreadLocalMap getMap(Thread t) {
       return t.inheritableThreadLocals;
    }

    void createMap(Thread t, T firstValue) {
        t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
    }
}

3.实战源码

具体的介绍,已经在我的博文,ThreadLocal使用及原理_编程还未的博客-优快云博客,介绍过了。

ThreadLocal实战,源码地址:highway-resources: threadlocal-current-user

关注公众号- 编程highway - 获取更多好文和学习资料

在多线程编程中,子线程默认无法直接访问父线程ThreadLocal变量,不过可以通过以下两种方法实现子线程父线程ThreadLocal数据的访问: - **使用InheritableThreadLocal**:InheritableThreadLocalThreadLocal类似,不同之处在于它允许子线程访问父线程ThreadLocal副本,即在子线程中可以获取父线程中的ThreadLocal副本的。示例代码如下: ```java public class MyInheritableThreadLocal { private static final InheritableThreadLocal<Integer> threadLocal = new InheritableThreadLocal<Integer>() { @Override protected Integer initialValue() { return 0; } }; public static void main(String[] args) { threadLocal.set(1); Thread thread = new Thread(() -> { int value = threadLocal.get(); System.out.println("继承的ThreadLocal子线程读取为: " + value); }); thread.start(); int value = threadLocal.get(); System.out.println("继承的ThreadLocal 在main线程读取为: " + value); } } ``` - **手动传递**:在创建子线程的时候将父线程ThreadLocal手动传递给子线程。示例代码如下: ```java package com.wyz.demo; public class ThreadLocalExample { private static final ThreadLocal<String> threadLocal = new ThreadLocal<>(); public static void main(String[] args) { threadLocal.set("Parent Thread Value"); // 获取父线程ThreadLocal String parentValue = threadLocal.get(); // 创建子线程并传递父线程ThreadLocal Thread childThread = new Thread(() -> { // 在子线程中设置父线程 threadLocal.set(parentValue); System.out.println("Child Thread: " + threadLocal.get()); }); childThread.start(); try { childThread.join(); // 等待子线程执行完毕 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Parent Thread: " + threadLocal.get()); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程还未

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值