目 录CONTENT

文章目录

深入解析InheritableThreadLocal实现原理

小张的探险日记
2021-12-15 / 0 评论 / 0 点赞 / 507 阅读 / 1,639 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2021-12-15,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

背景

前几天 在项目中集成hystrix,结果从ThreadLocal中获取不到数据。

原因:
hystrix(默认会使用线程隔离策略) 会隔离线程,提高系统的安全性

解决方案
把 ThreadLocal 换成 InheritableThreadLocal
案例:

public class ThreadLocalTest extends Thread{

    static ThreadLocal<String> threadLocal = new ThreadLocal<>();

    public static void main(String[] args){
        threadLocal.set("123");
        new ThreadLocalTest().start();
    }

    @Override
    public void run() {
        System.out.println(threadLocal.get()+"---");
    }
}

运行结果:
在main线程中给 ThreaLocal 设置值后,子线程中获取不到变量:

null---

Process finished with exit code 0

解决方案:

public class ThreadLocalTest extends Thread{

    static InheritableThreadLocal<String> threadLocal = new InheritableThreadLocal<>();

    public static void main(String[] args){
        threadLocal.set("123");
        new ThreadLocalTest().start();
    }

    @Override
    public void run() {
        System.out.println(threadLocal.get()+"---");
    }
}

123---

Process finished with exit code 0

使用 InheritableThreadLocal 解决了线程隔离获取不到变量的问题, 当然我们不能 知其然而不知道其所以然。那么为什么InheritableThreadLocal 可以在线程隔离的情况下获取到值呢? 让我们走进源代码:
这是 Thread 这段代码会在 Thread 初始化的时候执行, Thread 维护了 inheritableThreadLocals,threadLocals 两个变量 类型都是 ThreadLocalMap ,在下面这段代码中看到 它判断了inheritableThreadLocals 是否为空,不为空就传入 就把parent 的 inheritableThreadLocals 给到 当前线程的 this.inheritableThreadLocals

截屏20211215 下午3.05.06.png

可以看到 InheritableThreadLocal 重写了getMap,createMap方法,这两方法传入的参数都是Thread, return t.inheritableThreadLocals; 这里其实就是引用到了 上一步 返回到 Thread的inheritableThreadLocals变量

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

    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);
    }
}

这样我们就明白了,InheritableThreadLocal为什么能实现Thread的隔离还能获取变量。

0

评论区