ThreadLocal对象可以提供线程局部变量,每个线程Thread拥有一份自己的副本变量,多个线程互不干扰。
ThreadLocal的数据结构
- 用于让每个线程绑定自己的私有数据,一个
ThreadLocal变量对于不同的线程有不同的值,避免线程安全问题 - 底层是
ThreadLocalMap,类似于HashMap,可以看成以当前线程号为 key,值为 value- 实际 key 是当前线程的弱引用,如果垃圾回收,会清理掉 key,而 value 还会残留,导致内存泄露
- 如果 key 是强引用,那么如果当前线程不想用这个 TheadLocal 变量,将其置为 null,但是当前线程一直存活,那么这个TheadLocal实例还是一直有引用指向,就一直不会被清理
- 不是很懂什么时候会出现弱引用回收
- 常用方法:(都会清理掉 key 为 null 的记录)
- set:如果 key 不存在,插入元素
- 如果槽为空,直接插入
- 如果槽不为空,且是新数据,往后遍历,找到第一个槽为空的位置,插入
- 如果遍历过程发现 key 为 null 的数据,替换掉(清理操作)
- 如果中途发现相同的 key,执行更新操作
- get:获取元素
- 如果 hash 对应的槽有数据,但是 key 不同,也会往后查找,查找过程也会清理 key 为 null 的数据
- remove:删除元素
- 最好每次用的时候调用一下,直接清理 null 的 key
- set:如果 key 不存在,插入元素
- 也会扩容,扩容前会先清理 key 为 null 的数据,重新计算 hash,重新安放
- 实际 key 是当前线程的弱引用,如果垃圾回收,会清理掉 key,而 value 还会残留,导致内存泄露
- 应用场景:数据库连接的上下文
