01.ThreadLocal
2021-09-17 17:04:10 0 举报
登录查看完整内容
ThreadLocal 源码分析
作者其他创作
大纲/内容
TtlRunnable.run()
<TransmittableThreadLocal<?>font color=\"#f44336\
table(类型是 Entry,key 为 TransmittableThreadLocal,value 为对应存储的值)
new Thread()#<init>
InheritableThreadLocal.get()
1. 遍历当前线程 holder 中的所有 TTL 变量,将其放到 backup map 中2. 如果 capturedMap(即父线程中的所有 TTL)不存在就删除,确保当前线程不会引入其他的 TTL 变量3. setTtlValuesTo(capturedMap) 把父线程中的 TTL 变量放入到当前线程中,确保当前线程中的 TTL 变量值与父线程保持一致
1. Thread t = Thread.currentThread() 获取当前线程2. font color=\"#f44336\
table(类型是 Entry,key 为 InheritableThreadLocal,value 为对应存储的值)
ThreadLocal.get()
table(类型是 Entry,key 为 threadLocal,value 为对应存储的值)
1. Thread t = Thread.currentThread() 获取当前线程2. ThreadLocalMap map = getMap(t) 根据当前线程获取 ThreadLocalMap,因为被 InheritableThreadLocal 重写了这个方法,所以会返回 inheritableThreadLocals 属性3. font color=\"#f44336\
在子线程逻辑中获取值
TransmittableThreadLocal.set()
1. Thread t = Thread.currentThread() 获取当前线程2. ThreadLocalMap map = getMap(t) 根据当前线程获取 ThreadLocalMap,其实就是直接返回 threadLocals 属性3. font color=\"#f44336\
this.capturedRef = new AtomicReference<Object>(capture()) 将 holder 中存储的 TransmittableThreadLocal 以及 value 组装成 map 赋值给 capturedRef 对象,也就是先把当前线程(父线程)的 TransmittableThreadLocal 信息给备份下来
Thread(内部有一个局部变量 threadLocals,每个线程可以有多个 ThreadLocal)
Entry<TransmittableThreadLocalfont color=\"#f44336\
Thread(内部有一个局部变量 inheritableThreadLocals,每个线程可以有多个 TransmittableThreadLocal,这里以 2 个 TTL 为例)
提交 runnable 任务
1. super.set(value) 调用 InheritableThreadLocal.set() 方法2. addValue() 即把 TransmittableThreadLocal 放到 holder 持有的 map 中注意:1 个 ttl 的 set 操作会存储 2 个值,一个是 ttl,一个是 holder 对象,其中 holder 里的 WeakHashMap 存储了所有 ttl,value 均为 null,相当于线程可以通过 holder 查找到 ttl 变量,holder 类型为 itl(n 个 ttl 操作会使 inheritableThreadLocals 中存储 n+1 个值)
1. Thread t = Thread.currentThread() 获取当前线程2. ThreadLocalMap map = getMap(t) 根据当前线程获取 ThreadLocalMap,因为被 InheritableThreadLocal 重写了这个方法,所以会返回 inheritableThreadLocals 属性3. ThreadLocalMap.Entry e = map.getEntry(this) 从 inheritableThreadLocals 中获取当前 ThreadLocal 中对应的 Entry 对象,就是遍历 table 数组获取4. T result = (T)e.value 返回 entry 中的 value 值5. setInitialValue() 注意如果没有值,它会调用 createMap() 初始化,即添加到 inheritableThreadLocals 中span style=\
在子线程中获取值
1. super.get(value) 调用 InheritableThreadLocal.get() 获取值2. if (null != value) addValue() 如果 value 不为空,执行 addValue(),即把当前的 TTL 放到 holder 持有的 map 中
inheritableThreadLocals(类型是 ThreadLocal.ThreadLocalMap,内部有一个局部变量 table 数组)
Entry<TransmittableThreadLocal$1font color=\"#f44336\
ThreadLocal.set()
1. 遍历当前线程 holder 中的所有 TTL 变量,如果 backup(即线程执行 run 方法之前的所有 TTL 变量)不存在就删除,确保当前线程不会引入其他的 TTL 变量2. setTtlValuesTo(backupMap) 恢复线程执行 run 方法之前的所有 TTL 变量
子线程执行 run 方法
1. capturedRef.get() 获取之前父线程中存储的 TransmittableThreadLocal 信息2. Object backup = replay(captured) 执行回放过程,重点 ①3. runnable.run() 子线程真正的执行逻辑4. restore(backup) 使用 backup 恢复子线程的原有环境,重点 ②
InheritableThreadLocal.set()
if (parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);如果当前线程的 inheritableThreadLocals 不为空,就给 new 出来的 Thread 对象初始化 inheritableThreadLocals
new TtlRunnable()#<init>
threadLocals(类型是 ThreadLocal.ThreadLocalMap,内部有一个局部变量 table 数组)
当前线程获取值
初始化一个子线程
Thread(内部有一个局部变量 inheritableThreadLocals,每个线程可以有多个 InheritableThreadLocal)
TransmittableThreadLocal.get()
0 条评论
回复 删除
下一页