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);
for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { ThreadLocal<?> k = e.get();
for 循环里面的 if (k == key) 之后的代码,应该就是 注释里面解释的,对一个 新的 ThreadLocal 的处理逻辑
1 2 3 4
// 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.
ThreadLocal.get
1 2 3 4 5 6 7 8 9 10 11 12 13
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; } } return setInitialValue(); }
//ThreadLocal.remove publicvoidremove(){ ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null) m.remove(this); }
//ThreadLocalMap.remove privatevoidremove(ThreadLocal<?> key){ 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)]) { if (e.get() == key) { e.clear(); expungeStaleEntry(i); return; } } }