/** * 该类继承了WeakReference是方便垃圾回收,在底层map扩容之前进行entry的回收, * 减少扩容的概率,提高性能 */ staticclassEntryextendsWeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value;
// Rehash until we encounter null Entry e; int i; // 从staleSlot开始向后扫描一段连续的entry for (i = nextIndex(staleSlot, len); (e = tab[i]) != null; i = nextIndex(i, len)) { ThreadLocal<?> k = e.get(); //如果遇到key为null,表示无效entry,进行清理. if (k == null) { e.value = null; tab[i] = null; size--; } else { //如果key不为null,计算索引 int h = k.threadLocalHashCode & (len - 1); /** * 计算出来的索引——h,与其现在所在位置的索引——i不一致,置空当前的table[i] * 从h开始向后线性探测到第一个空的slot,把当前的entry挪过去。 */ if (h != i) { tab[i] = null;
// Unlike Knuth 6.4 Algorithm R, we must scan until // null because multiple entries could have been stale. while (tab[h] != null) h = nextIndex(h, len); tab[h] = e; } } } //下一个为空的solt的索引。 return i; }
/** * 启发式的扫描清除,扫描次数由传入的参数n决定 * * @param i 从i向后开始扫描(不包括i,因为索引为i的Slot肯定为null) * * @param n 控制扫描次数,正常情况下为 log2(n) , * 如果找到了无效entry,会将n重置为table的长度len,进行段清除。 * * map.set()点用的时候传入的是元素个数,replaceStaleEntry()调用的时候传入的是table的长度len * * @return true if any stale entries have been removed. */ privatebooleancleanSomeSlots(int i, int n){ boolean removed = false; Entry[] tab = table; int len = tab.length; do { i = nextIndex(i, len); Entry e = tab[i]; if (e != null && e.get() == null) { n = len; removed = true; i = expungeStaleEntry(i); } } while ( (n >>>= 1) != 0); return removed; }
/** * Re-pack and/or re-size the table. First scan the entire * table removing stale entries. If this doesn't sufficiently * shrink the size of the table, double the table size. */ privatevoidrehash(){ //全清理 expungeStaleEntries();
public T get(){ //同set方法类似获取对应线程中的ThreadLocalMap实例 Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } //为空返回初始化值 return setInitialValue(); } /** * 初始化设值的方法,可以被子类覆盖。 */ protected T initialValue(){ returnnull; }
private T setInitialValue(){ //获取初始化值,默认为null(如果没有子类进行覆盖) T value = initialValue(); Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); //不为空不用再初始化,直接调用set操作设值 if (map != null) map.set(this, value); else //第一次初始化,createMap在上面介绍set()的时候有介绍过。 createMap(t, value); return value; }
private ThreadLocal.ThreadLocalMap.Entry getEntry(ThreadLocal<?> key){ //根据key计算索引,获取entry int i = key.threadLocalHashCode & (table.length - 1); ThreadLocal.ThreadLocalMap.Entry e = table[i]; if (e != null && e.get() == key) return e; else return getEntryAfterMiss(key, i, e); }
/** * 通过直接计算出来的key找不到对于的value的时候适用这个方法. */ private ThreadLocal.ThreadLocalMap.Entry getEntryAfterMiss(ThreadLocal<?> key, int i, ThreadLocal.ThreadLocalMap.Entry e){ ThreadLocal.ThreadLocalMap.Entry[] tab = table; int len = tab.length;
while (e != null) { ThreadLocal<?> k = e.get(); if (k == key) return e; if (k == null) //清除无效的entry expungeStaleEntry(i); else //基于线性探测法向后扫描 i = nextIndex(i, len); e = tab[i]; } returnnull; }