解决ThreadLocal在开启子线程时,父线程向子线程值传递问题,源码分析

有关ThreadLocal的介绍我之前一篇文章已经做了介绍:https://blog.csdn.net/qq_26012495/article/details/86475725

本篇主要解决,在父线程中开启子线程时ThreadLocal存在的值传递问题,以及如何解决。

 

目录

 

一、ThreadLocal

1. 普通ThreadLocal存在的问题

二、InheritableThreadLocal 

1. InheritableThreadLocal源码分析

2. Thread类源码分析

 3. 修改为InheritableThreadLocal代码测试

4. InheritableThreadLocal在其他场景存在的问题

三、TransmittableThreadLocal(阿里开源)

1. 查看TransmittableThreadLocal源码

2. TtlExecutors类使用及源码分析


一、ThreadLocal

1. 普通ThreadLocal存在的问题

先使用普通的ThreadLocal类做一个测试,在main方法中通过new Thread方法来开启子线程,在子线程中打印父线程中set的ThreadLocal值。

public static void main(String[] args) throws Exception {

        ThreadLocal<String> threadLocal = new ThreadLocal<>();
        threadLocal.set("初始化的值能继承吗?");

        System.out.println("父线程的ThreadLocal值:" + threadLocal.get());
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("子线程到了");
                System.out.println("子线程的ThreadLocal值:" + threadLocal.get());
            }
        }).start();
    }

子线程打印的结果为null,说明父线程的ThreadLocal值在子线程中并未得到传递,而是中断了。 

二、InheritableThreadLocal 

1. InheritableThreadLocal源码分析

由于ThreadLocal父线程无法传递本地变量到子线程中,于是JDK引入了InheritableThreadLocal类,该类的首部描述:该类继承了ThreadLocal类,用以实现父线程到子线程的值继承;创建子线程时,子线程将接收父线程具有值的所有可继承线程局部变量的初始值。通常子线程的值与父线程相同;子线程的值可以被父线程重写的方法改变;

/**
 * This class extends <tt>ThreadLocal</tt> to provide inheritance of values
 * from parent thread to child thread: when a child thread is created, the
 * child receives initial values for all inheritable thread-local variables
 * for which the parent has values.  Normally the child's values will be
 * identical to the parent's; however, the child's value can be made an
 * arbitrary function of the parent's by overriding the <tt>childValue</tt>
 * method in this class.
 *
 * <p>Inheritable thread-local variables are used in preference to
 * ordinary thread-local variables when the per-thread-attribute being
 * maintained in the variable (e.g., User ID, Transaction ID) must be
 * automatically transmitted to any child threads that are created.
 *
 * @author  Josh Bloch and Doug Lea
 * @see     ThreadLocal
 * @since   1.2
 */

public class InheritableThreadLocal<T> extends ThreadLocal<T> {
  

共有如下三个方法,没有什么特殊的地方: 

public class InheritableThreadLocal<T> extends ThreadLocal<T> {
    /**
     * Computes the child's initial value for this inheritable thread-local
     * variable as a function of the parent's value at the time the child
     * thread is created.  This method is called from within the parent
     * thread before the child is started.
     * <p>
     * This method merely returns its input argument, and should be overridden
     * if a different behavior is desired.
     *
     * @param parentValue the parent thread's value
     * @return the child thread's initial value
     */
    protected T childValue(T parentValue) {
        return parentValue;
    }

    /**
     * Get the map associated with a ThreadLocal.
     *
     * @param t the current thread
     */
    ThreadLocalMap getMap(Thread t) {
       return t.inheritableThreadLocals;
    }

    /**
     * Create the map associated with a ThreadLocal.
     *
     * @param t the current thread
     * @param firstValue value for the initial entry of the table.
     */
    void createMap(Thread t, T firstValue) {
        t.inherit
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值