ThreadLocalMap getMap(Thread t) { return t.inheritableThreadLocals; }
void createMap(Thread t, T firstValue) { t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue); }}```InheritableThreadLocal的源代码并不多,主要是**覆盖了ThreadLocal的三个方法childValue、getMap、createMap 。**<br />childValue方法用于ThreadLocalMap内部使用,我们不打算讲解ThreadLocalMap内部设计,这里可以忽略;<br />ThreadLocal本来getMap、createMap读写的是当前Thread对象的threadLocals变量 。<br />而InheritableThreadLocal将其改为了读写当前Thread对象的InheritableThreadLocal变量 。
接着我们要从Thread类的源码查找头绪 。
Thread类源代码中,我们可以看到有这么2个成员变量:```javaThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;```**如果是使用ThreadLocal创建线程变量,读写的是Thread对象的threadLocals;**<br />**如果是使用InheritableThreadLocal创建线程变量,读写的是Thread对象的inheritableThreadLocals 。**
在Thread类的init方法可以看到(Thread所有构造方法都是调用init方法,这边仅贴出关键部分):```javaif (parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);```ThreadLocal.createInheritedMap:```javastatic ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) { return new ThreadLocalMap(parentMap);}```**如果父级线程的inheritableThreadLocals不为null,那么将父级线程的inheritableThreadLocals赋值到当前线程的inheritableThreadLocals变量 。**
总结:当使用InheritableThreadLocal创建线程变量时,父线程读写线程变量实际是写入父线程的inheritableThreadLocals中,在创建子线程时,会将父线程的inheritableThreadLocals复制给子线程的inheritableThreadLocals,子线程操作此线程变量时,也是读写自己线程的inheritableThreadLocals,这就达到了子线程可以获取父线程ThreadLocal的效果 。
# 其他要点
- 如果使用了线程池,线程是会被复用的,因此线程的threadLocals和inheritableThreadLocals也会复用,在线程池使用ThreadLocal可能会产生一些问题,需要留意;- JDK本身提供创建线程池的方法,是不支持获得父级线程的ThreadLocal变量的 。
经验总结扩展阅读
- 2023年9月14日迁居行吗 2023年9月14日是迁居的黄道吉日吗
- 家里干净怎么会有跳蚤
- 2023年10月5日是搬家的吉日吗 是吉祥的日子吗
- 油的沸点是多少度?
- 煮熟的虾怎么保存 冷藏还是冷冻
- 2023年10月12日搬家怎么样 是吉祥的日子吗
- 鞋子磨脚怎么办小妙招
- 2023年9月14日祭祖吉日一览表 2023年9月14日是祭祖的黄道吉日吗
- 酒驾20到80之间处罚一样吗
- 米字旗是哪国的国旗