ThreadLocal
from: ThreadLocal explained
java.lang.Thread
public class Thread implements Runnable { // 每個thread 都有一個ThreadLocalMap 來保存自己的ThreadLocal變數 ThreadLocal.ThreadLocalMap threadLocals = null; }
java.lang.ThreadLocal
// 1. 取得當前Thread實體 // 2. 取得ThreadLocalMap // 3. 如果ThreadLocalMap或threadlocal是null(第一次呼叫),設定初始值 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; } // 1. 取得初始值 // 2. 取得ThreadLocalMap // 3. 存入value // a. 如果ThreadLocalMap是null, 建立map // b. 直接將(threadlocal, value)存入map // 4. 回值value private T setInitialValue() { T value = initialValue(); Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); return value; } // 預設為null,可被overwirte protected T initialValue() { return null; } void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } // 1. 取得當前Thread // 2. 取得ThreadLocalMap // 3. 存入value // a. 如果ThreadLocalMap是null, 建立map // b. 將(threadlocal, value)存入map public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
ThreadLocal.ThreadLocalMap
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); } static class Entry extends WeakReference<ThreadLocal<?>> { Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } } private Entry[] table; private Entry getEntry(ThreadLocal<?> key){...}; private void set(ThreadLocal<?> key, Object value){...}; private void remove(ThreadLocal<?> key){...};