ThreadLocal 对象可提供线程局部变量,每个线程拥有一份自己的副本变量,多个线程互不干扰
- 结构
- Thread 类有个 ThreadLocal.ThreadLocalMap 的实例变量 threadLocals,每个线程有一个自己的ThreadLocalMap
- ThreadLocalMap 的 key 为 ThreadLocal,value 为代码中放入的值(key 是 ThreadLocal 的弱引用,GC 后可能被回收造成内存泄露)
- 每个线程往 ThreadLocal 里放值时,会往自己的 ThreadLocalMap 里存,读也是以 ThreadLocal 为引用,在自己的 map 里找对应 key,实现线程隔离
- HashMap 是由数组+链表实现,ThreadLocalMap 没有链表结构
- Entry 的 key 是 ThreadLocal<?> k ,继承自 WeakReference(弱引用类型)
ThreadLocal.set()
ThreadLocalMap.set()
- hash 计算后槽位对应 Entry 数据为空,直接插入
- 槽位数据不为空,key 值与当前 ThreadLocal 通过 hash 计算的 key 值一致,直接更新
- 槽位数据不为空,往后遍历,找到 Entry 为 null 的槽位前,没有遇到 key 过期的 Entry,继续遍历散列数组,找到 Entry 为 null 的槽位将数据放入该槽位中,或遇到 key 值相等的数据直接更新
- 槽位数据不为空,往后遍历,找到 Entry 为 null 的槽位前,遇到 key 过期的 Entry(key 为 null)
执行 replaceStaleEntry(),替换过期数据,以过期 Entry 为起点开始向前迭代查找,找其他过期的数据,然后更新过期数据起始扫描下标slotToExpunge。for循环迭代,直到碰到Entry为null结束
- ThreadLocalMap Hash 算法 ```java int i = key.threadLocalHashCode & (len-1); //i是当前key在散列表中对应数组下标
public class ThreadLocal
- ThreadLocalMap Hash 冲突
- 线性向后查找到 Entry 为 null 的槽才停止,将当前元素放入此槽中