说 InheritableThreadLocal 之前我们先说下ThreadLocal
可以去看看 : 对ThreadLocal的思考
背景
前几天 在项目中集成hystrix,结果从ThreadLocal中获取不到数据。
原因
hystrix 会隔离线程,提高系统的安全性
解决方案
把 ThreadLocal 换成 InheritableThreadLocal
案例:
1 |
|
运行结果: 子线程中 获取不到 变量
1 |
null--- |
//解决方案
1 |
public class extends Thread{ |
1 |
123--- |
使用 InheritableThreadLocal 解决了线程隔离获取不到变量的问题,
当然我们不能 知其然而不知道其所以然。
那么为什么InheritableThreadLocal 可以在线程隔离的情况下获取到值呢?
让我们走进源代码:
这是 Thread 的源代码的部分源码大概在418行,这段代码会在 Thread 初始化的时候执行,
Thread 维护了 inheritableThreadLocals,threadLocals 两个变量 类型都是 ThreadLocalMap
,在下面这段代码中看到 它判断了inheritableThreadLocals 是否为空,不为空就传入 createInheritedMap 往下看 createInheritedMap的源码
1 |
if (inheritThreadLocals && parent.inheritableThreadLocals != null) |
此处生成了一个新增 ThreadLocalMap 返回 然后 赋值给了 Thread的this.inheritableThreadLocals,
流程就是
Thread初始化->创建一个新的ThreadLocalMap(存储了当前线程变量的)返回—->这步 看 InheritableThreadLocal的源码
1 |
static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) { |
可以看到 InheritableThreadLocal 重写了getMap,createMap方法,这两方法传入的参数都是Thread, return t.inheritableThreadLocals; 这里其实就是引用到了 上一步 返回到 Thread的inheritableThreadLocals变量
1 |
public class InheritableThreadLocal<T> extends ThreadLocal<T> { |
这样我们就明白了,InheritableThreadLocal为什么能实现Thread的隔离还能获取变量。
如果本文对您有帮助,请不要吝啬您的点赞。谢谢!
近期评论