threadlocal的过期数据_threadlocal详解

这篇博客详细介绍了ThreadLocal的工作原理,包括每个线程的ThreadLocalMap结构,其中Entry使用弱引用作为key来处理过期数据。当ThreadLocal对象被垃圾回收时,对应的Entry key变为空,便于识别过期Entry。ThreadLocalMap在查找过程中,通过expungeStaleEntry方法优化,回收过期数据并调整冲突的Entry位置。当Entry数量达到一定比例时,会触发扩容或清理操作。
摘要由CSDN通过智能技术生成

threadlocal定义:每个线程有自己的数据 其他的线程拿不到

每个线程本身有一个threadlocals属性(类型是ThreadLocalMap),map中存储的entry的key是当前线程的threadlocal对象,value是自定义的值

ThreadLocalMap中的静态内部类Entry结构

static class Entry extends WeakReference>{

// 当前线程关联的threadlocal的value值Object value;

Entry(ThreadLocal>k, Object v) {super(k);

value=v;

}

}

注意entry的key是个弱引用,value是个强引用

那么为什么entry要设计成弱引用呢?

threadlocal对象被gc回收的时候 线程的threadlocalmap中相对应的entry的key变为null

可以区分哪些entry是过期的

注意:ThreadlocalMap类是静态内部类 是共享的数据

threadlocalmap放入元素的时候如果发生hash冲突 是不会转化为链表存储的,会向slot后查找可以存放的桶位,查找的时候也是这样

查找方法最核心的方法是:

1 private int expungeStaleEntry(intstaleSlot) { // 这个方法是用来优化查找 优化过期数据,目的是帮助过期数据让gc回收,让hash冲突的entry找到尽可能正确的位置

// 执行这个方法的时候说明查找的entry没找到并且key等于null staleSlot代表key为null的索引2 Entry[] tab =table;3 int len =tab.length;4

5 //expunge entry at staleSlot

6 tab[staleSlot].value = null;7 tab[staleSlot] = null;8 size--;9

10 //Rehash until we encounter null

11 Entry e;12 inti;13 for (i =nextIndex(staleSlot, len);14 (e = tab[i]) != null;15 i =nextIndex(i, len)) { //查找到entry不为null的索引16 ThreadLocal> k =e.get();17 if (k == null) { //key失效了18 e.value = null;19 tab[i] = null;20 size--;21 } else{22 //查到到的entry不是过期数据

23 int h = k.threadLocalHashCode & (len - 1);24 //并且就是位置不正确的entry 正确位置是h i是查找出来的entry的当前位置

25 if (h != i) {//h!=i说明位置发生了偏移了26 //将entry当前位置设置为null 也就是i设置为null

27 tab[i] = null;28

29 //Unlike Knuth 6.4 Algorithm R, we must scan until30 //null because multiple entries could have been stale.31 //如果h位置被占用了 就往后查找最靠近正确位置的index 找到就存入数据

32 while (tab[h] != null)33 h =nextIndex(h, len);34 tab[h] =e;35 }36 }37 }38 returni;39 }

threadlocal的entry数组中entry的size大于等于数组长度的3分之2进行rehash,扩容rehash前回先清除一下key失效的entry,如果清理过后entry的数量还大于等于threhold的4分之3

进行数组扩容并重新计算entry的下标

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值