/** * The initial capacity -- MUST be a power of tw */ privatestaticfinalint INITIAL_CAPACITY = 16; /** * The table, resized as necessary. * table.length MUST always be a power of two. */ private Entry[] table; /** * The number of entries in the table. */ privateint size = 0; /** * The next size value at which to resize. */ privateint threshold; // Default to 0
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; }
3.3expungeStaleEntries
扫描整个 Entry 数组
1 2 3 4 5 6 7 8 9
privatevoidexpungeStaleEntries(){ Entry[] tab = table; int len = tab.length; for (int j = 0; j < len; j++) { Entry e = tab[j]; if (e != null && e.get() == null) expungeStaleEntry(j); } }
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; int i = key.threadLocalHashCode & (len-1); // 若没有hash冲突,则直接插入 // 若存在hash冲突,则调用 nextIndex 遍历后面的节点,直到找到可插入的节点 for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { ThreadLocal<?> k = e.get(); // key 值相等,直接替换 if (k == key) { e.value = value; return; } // key值无效,则替换 if (k == null) { replaceStaleEntry(key, value, i); return; } } tab[i] = new Entry(key, value); int sz = ++size; // 试图清除一些节点 // 若没有需要清除的节点,且数据长度达到了 theshold,则rehash对entry数组进行调整 if (!cleanSomeSlots(i, sz) && sz >= threshold) rehash(); }
private Entry getEntry(ThreadLocal<?> key){ int i = key.threadLocalHashCode & (table.length - 1); Entry e = table[i]; if (e != null && e.get() == key) return e; else return getEntryAfterMiss(key, i, e); }
getEntryAfterMiss
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
private Entry getEntryAfterMiss(ThreadLocal<?> key, int i, Entry e){ Entry[] tab = table; int len = tab.length; while (e != null) { ThreadLocal<?> k = e.get(); if (k == key) // 命中key,返回 return e; if (k == null) // 无效节点,清除 expungeStaleEntry(i); else i = nextIndex(i, len); e = tab[i]; } // 至此,未命中 返回null returnnull; }
public T get(){ 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; } } // 没有获取到value,则插入默认值并返回 return setInitialValue(); }