ThreadLocal
- Thread 有一个成员变量 ThreadLocal.ThreadLocalMap threadLocals
- 读写的时候,其实是 所在线程 的成员变量里 get/set/remove
- ThreadLocalMap 是一个简单的Map结构
- 存储结构 是 Entry[] 数组, 线性探测法
class Entry extends WeakReference<ThreadLocal<?>>
- 每次 getEntryAfterMiss/set/remove 时,会检查后续节点,清理null
- 发现 ThreadLocal已经是null
- 就将 value 和 Entry自身指向 Null,可被gc回收
- ThreadLocal用法特点,即使忘记remove,后续的 set 也会帮助内存回收,
- 弱引用的优势,就在于,“如果忘记remove”
ThreadLocal 讨论
阿滔: 如果是强引用,什么场景会导致BUG
阿滔: 每次new 新的threadLocal, 做set设值
阿滔: 只有当整个线程回收的时候,会清理
阿滔: 明确问题 1. 强引用的话,是不是很容易导致bug(忘记remove); 2. 弱引用,解决了什么; 3. 什么场景还有问题
【问题1解答】
阿滔: 就像connection需要close一样,反复创建新的threadLocal,会有问题,主要问题是不容易发现
【问题2解答】
阿滔: 解决了反复创建threadLocal对象的问题;不能解决的场景:
【问题3解答】
阿滔: 若干线程,每个都持有Entry,且无后续set/remove,且Thread一直存活–》Value就会一直保留强引用,无法释放,
阿滔: 只存在弱引用的对象,会被清理
阿滔: 所以 使用/创建 threadLocal 的地方如果还在,threadLocal就不会被清理;只有当 使用/创建 threadLocal 的地方不在了,比如某个方法反复创建,就会清理
大牛: 不存在ThreadLocal错误使用影响线程回收的例子