ThreadLocalMap是ThreadLocal类的静态内部类,用于保存本地线程变量。它采用除留余数法和线性探测法,以ThreadLocal.threadLocalHashCode为键,以本地线程变量为值。
存储结构
当键为null,即entry.get() == null时,表示该键不再被引用。这些键为null的项,被称之为”stale entries”。
1 | // Entry的键被弱引用关联:当下一次垃圾收集发生时,将被回收掉 |
构造方法
1 | ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) { |
1.声明INITIAL_CAPACITY的源码如下:
1 | // 默认容量为16(容量必须是2的整数次幂) |
2.声明firstKey.threadLocalHashCode变量的源码如下:
1 | public class ThreadLocal<T> { |
3.setThreshold(INITIAL_CAPACITY)的源码如下:
1 | // 阈值 = 容量 * 负载因子,负载因子为2/3 |
添加元素
1 | private void set(ThreadLocal<?> key, Object value) { |
1.nextIndex(i, len)的源码如下:
1 | // i = (i + 1) % len; |
2.e.get()
方法返回当前项的键,其源码如下:
1 | public abstract class Reference<T> { |
3.replaceStaleEntry(key, value, i)的源码如下:
1 | // expunge 删掉 |
4.prevIndex(staleSlot, len)的源码如下:
1 | // i = (i - 1 + len) % len; |
5.expungeStaleEntry(slotToExpunge)的源码如下:
1 | // 返回下一个空槽的下标 |
.
1 | // 清空已经被回收的槽 |
重新哈希
1 | private void rehash() { |
1.expungeStaleEntries()方法用于删除哈希表中所有已经被回收的项,其源码如下:
1 | private void expungeStaleEntries() { |
resize()用于对哈希表进行扩容,新的容量为原来容量的2倍,源码如下:
1 | private void resize() { |
取值操作
1 | private Entry getEntry(ThreadLocal<?> key) { |
若存在哈希冲突,则调用getEntryAfterMiss方法。
1 | // 采用线性探测法,寻找key所在的项 |
删除操作
1 | private void remove(ThreadLocal<?> key) { |
clear()方法的源码如下:
1 | public abstract class Reference<T> { |