privatevoidset(ThreadLocal <?> key, Object value) { // We don't use a fast path as with get() because it is at // least as common to use set() to create new entries as // it is to replace existing ones, in which case, a fast // path would fail more often than not. Entry[] tab = table; int len = tab.length; // 根据 ThreadLocal 的散列值,查找对应元素在数组中的位置 int i = key.threadLocalHashCode & (len - 1); // 使用线性探测法查找元素 for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { ThreadLocal <?> k = e.get(); // ThreadLocal 对应的 key 存在,直接覆盖之前的值 if (k == key) { e.value = value; return; } // key为 null,但是值不为 null,说明之前的 ThreadLocal 对象已经被回收了,当前数组中的 Entry 是一个陈旧(stale)的元素 if (k == null) { // 用新元素替换陈旧的元素,这个方法进行了不少的垃圾清理动作,防止内存泄漏,具体可以看源代码,没看太懂 replaceStaleEntry(key, value, i); return; } } // ThreadLocal 对应的 key 不存在并且没有找到陈旧的元素,则在空元素的位置创建一个新的 Entry。 tab[i] = new Entry(key, value); int sz = ++size; // cleanSomeSlot 清理陈旧的 Entry(key == null),具体的参考源码。如果没有清理陈旧的 Entry 并且数组中的元素大于了阈值,则进行 rehash。 if (!cleanSomeSlots(i, sz) && sz >= threshold) rehash(); }
Java并发编程ThreadLocal 详解
内容版权声明:除非注明,否则皆为本站原创文章。
转载注明出处:https://www.heiqu.com/f7994784e867991852ab82db1be791ac.html