赞
踩
线程变量存放在当前线程变量中,线程上下文中,set将变量添加到threadLocals变量中
Thread类中定义了两个ThreadLocalMap类型变量threadLocals、inheritableThreadLocals用来存储当前操作的ThreadLocal的引用及变量对象,把当前线程的变量和其他的线程的变量之间进行隔离,从而实现了线程的安全性
InheritableThreadLocal类重写get/set方法会对线程的inheritableThreadLocals变量初始化,在对子线程初始化时将子线程的inheritableThreadLocals变量赋值为父线程的inheritableThreadLocals变量值,实现了子线程继承父线程
Thread->ThreadLocalMap->Entry->value,ThreadLocalMap是继承了WeakReference的entry集合,但是线程一直没有remove,threadLocal下次GC将弱引用对象回收,entry对象的key为null,value值却是强引用关系
ThreadLocal每次调用get、set、remove的时候都会直接或者间接的调用expungeStaleEntry方法清除掉key为null的Entry;
主线程执行ThreadLocal.remove()后,子线程中的ThreadLocal并不会被remove()判空,导致线程池中维护的ThreadLocal存储的值一直不变
没找到对应的InheritableThreadLocal 自然改不了:普通的ThreadLocal会让子线程获取不到get值
池化:减少资源对象创建次数
- private void init(ThreadGroup g, Runnable target, String name,
- long stackSize, AccessControlContext acc,
- boolean inheritThreadLocals) {
- //省略部分代码
-
- //如果父线程inheritableThreadLocals不为空,则保存下来
- if (inheritThreadLocals && parent.inheritableThreadLocals != null)
- this.inheritableThreadLocals =
- ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
-
- //省略部分代码
- }
注意 使用静态和不使用静态时候
使用静态的InheritableThreadLocal 线程池复用时候不会有问题
ThreadLocal是线程本地变量,每个线程有自己的副本;InheritableThreadLocal具有继承性,在创建子线程时,子线程可以继承父线程的变量副本。
https://www.cnblogs.com/shanheyongmu/p/17922183.html
https://www.cnblogs.com/tiancai/p/17622821.html InheritableThreadLocal详解 - 简书
继承自InheritableThreadLocal,在线程池中传递ThreadLocal变量的值
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。