前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >源码解析:ThreadLocal(3)

源码解析:ThreadLocal(3)

作者头像
爪哇缪斯
发布2023-05-09 21:49:06
1370
发布2023-05-09 21:49:06
举报
文章被收录于专栏:爪哇缪斯

3.5> replaceStaleEntry(key, value, i)

  • 当发现待插入的位置上已经被其他Entry占用了,并且它的key值与我们不同(即:不是同一个ThreadLocal实例),那么,当这个已存在的Entry元素key==null的时候,逻辑上就走到了第二个红框里的方法——replaceStaleEntry(key, value, i),该方法是用来替换“陈旧的”Entry的。下面我们来看一下这个方法的代码和注释:
  • 流程图如下所示:
  • 向前遍历的示意图如下所示:
  • 向后遍历的示意图如下所示:
  • 结合向前遍历和向后遍历(以case2为例)的两部分,最终的结果如下所示:

3.6> expungeStaleEntry(int staleSlot)

  • 上面介绍完了replaceStaleEntry方法之后,我们发现,方法里面都调用了如下方法:

【注意】

方法的入参是slotToExpunge,它代表的含义是——我们上面“施工”范围内,最左侧的“陈旧”Entry下标位置。

其实也就是说,下面的清理工作,是以slotToExpunge作为起点,然后在“施工”范围内,向后一个个遍历处理“陈旧”Entry。

  • cleanSomeSlots这个方法在开篇的set方法的源码截图中用红框标注过,也算是我们见过面的方法了。但是expungeStaleEntry方法我们是第一次见到了,那么我们就先来分析它吧。还是老样子,源码和注释如下所示:

【解释】

  • 以slotToExpunge作为起点进行遍历,如果发现k==null(即:“陈旧”Entry),那么就赋值e.value=null,当前位置的Entry=null,这样gc就可以对其进行回收了。
  • 下面还会对每个k不为null的正常Entry进行重新的下标定位,目的就是让后面的元素往前面移动,因为开放地址寻找元素的时候,遇到null就停止寻找了,由于上面if代码中,k==null的时候已经设置entry为null了,不移动的话,后面的元素就访问不到了。
  • 找到新的位置后,把Entry放到新的位置上,即:tab[h]=e;
  • 流程图如下所示:

后面的内容,参见:ThreadLocal源码精讲(4)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爪哇缪斯 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3.5> replaceStaleEntry(key, value, i)
  • 3.6> expungeStaleEntry(int staleSlot)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档