1. 程式人生 > >ThreadLocal原理

ThreadLocal原理

通過 失敗 return hash map init hash div stk clas

ThreadLocal類可以看作是當前線程的一個局部變量,只有當前線程可以訪問,因此是線程安全的。
ThreadLocal內部維護了一個ThreadLocalMap類,ThreadLocalMap是一個定制的hash map,用於維護ThreadLocal類的value。
首先來看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);
}

可以看到,set方法時將當前線程對象Thread作為key設置到ThreadLocalMap中去。
首先通過當前線程對象獲取到threadLocalMap對象,如果獲取到,則更新值,獲取失敗,則創建並更新值。

我們看看createMap的實現:

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對象內部維護了一個弱引用的Entry對象,Entry對象使用當前的ThreadLocal對象作為key。

再來看看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();
}

還是通過當前線程對象獲取到map,然後取出存放在map中的值。

最後,ThreadLocal對象的生命周期是線程的生命周期,它會先線程退出的時候 被銷毀,如果希望及時回收設置進ThreadLocal中的對象,可以手動調用ThreadLocal.remove()方法。防止內存泄漏。

ThreadLocal原理