ThreadLocal平時用的比較多,經過將變量在每一個線程放一個副本,避免了在多線程下對於變量的爭搶。多線程
ThreadLocal源碼比較簡單,總體瞭解起來比較容易。this
static class ThreadLocalMap {
ThreadLoca維護了內部類ThreadLocalMap。線程
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(); } ThreadLocalMap getMap(Thread t) { return t.threadLocals; } ThreadLocal.ThreadLocalMap threadLocals = null;
能夠發現經過線程獲取一個ThreadLocalMap,而值的獲取經過this(就是ThreadLocal)獲取一個Entry。code
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) { table = new Entry[INITIAL_CAPACITY]; int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1); table[i] = new Entry(firstKey, firstValue); size = 1; setThreshold(INITIAL_CAPACITY); }
數據放在ThreadLocalMap中,key是ThreadLocal。rem
public void remove() { ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null) m.remove(this); } private void remove(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; } } }
ThreadLocal核心代碼就這麼多吧,主要關注下里面的Entry,ThreadLocalMap。get