写点什么

ThreadLocal 源码分析

作者:zarmnosaj
  • 2022-10-18
    四川
  • 本文字数:1340 字

    阅读完需:约 1 分钟

类定义

首先看 ThreadLocal 的类定义上,是带有泛型标注的,说明 ThreadLocal 可以存储任意类的数据。


public class ThreadLocal<T> {}
复制代码


ThreadLocal 的属性:


private final int threadLocalHashCode = nextHashCode();
private static int nextHashCode() { return nextHashCode.getAndAdd(HASH_INCREMENT);}
private static AtomicInteger nextHashCode = new AtomicInteger();

static class ThreadLocalMap { static class Entry extends WeakReference<ThreadLocal<?>> { Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } }
private static final int INITIAL_CAPACITY = 16;
private Entry[] table;
private int threshold;}
......
复制代码


  • threadLocalHashCode 表示当前 ThreadLocal 的 hashCode,主要用于计算当前 ThreadLocal 对象 在 ThreadLocalMap 中的索引位置

  • nextHashCode() 主要是用于计算 ThreadLocal 对象 的 hashCode 值

  • nextHashCode 属性使用了 static 修饰,并且数据类型是 AtomicInteger,首先 AtomicInteger 保证了每个 ThreadLocal 的 threadLocalHashCode 是唯一的,当然这必须得在不同 JVM 中;其次 static 可以使得在同一时刻,多个 ThreadLocalMap 被 set 到 ThreadLocal 时,需要使用到 threadLocalHashCode 进行唯一区分

  • ThreadLocalMap 中的 Entry 表示数组中的每个节点值,继承了 WeakReference,表示当前对象在没有引用指向时,进行 JVM 垃圾回收时就会被回收掉

  • ThreadLocalMap 的数组的初始化大小为 16,扩容的初始阈值是数组大小的三分之二

ThreadLocalMap 的 set 方法

        private void set(ThreadLocal<?> key, Object value) {            Entry[] tab = table;            int len = tab.length;            int i = key.threadLocalHashCode & (len-1);
for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { ThreadLocal<?> k = e.get();
if (k == key) { e.value = value; return; }
if (k == null) { replaceStaleEntry(key, value, i); return; } }
tab[i] = new Entry(key, value); int sz = ++size; if (!cleanSomeSlots(i, sz) && sz >= threshold) rehash(); }
复制代码


int i = key.threadLocalHashCode & (len-1); 表示计算 key 在数组中的下标,其实就是 ThreadLocal 的 hashCode 和数组大小-1 取余


for 循环数组进行处理时 tab[i],首先查看 i 索引位置有没有值,有值的话,索引位置 + 1,直到找到没有值的位置


e = tab[i = nextIndex(i, len)])... nextIndex 就是让在不超过数组长度的基础上,把数组的索引位置 + 1


if (k == key) { e.value = value; return; } 找到内存地址一样的 ThreadLocal,直接替换


if (k == null) { ... } 判断当前 key 是否是 null,是则说明 ThreadLocal 被清理了,直接替换掉

发布于: 刚刚阅读数: 4
用户头像

zarmnosaj

关注

靡不有初,鲜克有终 2020-02-06 加入

成都后端混子

评论

发布
暂无评论
ThreadLocal 源码分析_10月月更_zarmnosaj_InfoQ写作社区