ThreadLocal源碼閱讀

ThreadLocal平時用的比較多,經過將變量在每一個線程放一個副本,避免了在多線程下對於變量的爭搶。多線程

ThreadLocal源碼比較簡單,總體瞭解起來比較容易。this

ThreadLocalMap

static class ThreadLocalMap {

ThreadLoca維護了內部類ThreadLocalMap。線程

get方法

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

set方法

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

remove方法

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

相關文章
相關標籤/搜索