ThreadLocal

ThreadLocal的 key 是弱引用,那么在 ThreadLocal.get()的时候,发生GC之后,key 是否为null

弱引用:

Thread类有一个类型为ThreadLocal.ThreadLocalMap的实例变量threadLocals,也就是说每个线程有一个自己的ThreadLocalMap

ThreadLocalMap有自己的独立实现,可以简单地将它的key视作ThreadLocalvalue为代码中放入的值(实际上key并不是ThreadLocal本身,而是它的一个弱引用)。

每个线程在往ThreadLocal里放值的时候,都会往自己的ThreadLocalMap里存,读也是以ThreadLocal作为引用,在自己的map里找对应的key,从而实现了线程隔离

题目说的是在做 ThreadLocal.get() 操作,证明其实还是有强引用存在的,所以 key 并不为 nullThreadLocal强引用仍然是存在的。

ThreadLocalThreadLocalMap数据结构

ThreadLocalMap有点类似HashMap的结构,只是HashMap是由数组+链表实现的,而ThreadLocalMap中并没有链表结构。

ThreadLocalMapHash 算法

i就是当前 key 在散列表中对应的数组下标位置,计算下标 i 最关键的就是利用threadLocalHashguanjianCode值的计算

int i = key.threadLocalHashCode & (len-1);

ThreadLocalMapHash 冲突如何解决?

过期 key 的产生

  • ThreadLocalMap 的键是弱引用(WeakReference),当 ThreadLocal 对象没有其他强引用时,它会被垃圾回收。
  • 被垃圾回收的键对应的 Entry 就变成了无效条目(stale entry),即 Entry.key == null

这些无效条目需要被清理,以释放内存并减少哈希冲突

核心方法是 线性探测法,并通过以下机制优化性能:

  1. 弱引用键:允许垃圾回收无效的 ThreadLocal 对象。
  2. 清理无效条目:在插入和访问时清理无效的 Entry
  3. 扩容机制:当条目数量过多时,扩展数组容量以减少冲突概率。

ThreadLocalMap扩容机制

扩容后数组长度变为原来的 2 倍。
然后遍历老的散列表,重新计算hash位置,然后放到新的tab数组中,如果出现hash冲突则往后寻找最近的entrynull的槽位,遍历完成之后,oldTab中所有的entry数据都已经放入到新的tab中了。

 

ThreadLocalMap过期 key 的清理机制探测式清理启发式清理流程?

探测式清理是以当前Entry 往后清理,遇到值为null则结束清理,属于线性探测清理

  • 全面清理无效条目,并重新排列有效条目。
  • 适用于插入、扩容等场景。

启发式清理是一种轻量级的清理机制,旨在快速处理部分无效条目,而不是对整个哈希表进行全面清理。

启发式清理通常在以下情况下触发:

  • set() 或 get() 操作时,探测到无效条目。
  • 哈希表中存在较多无效条目,但尚未达到全面清理的条件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值