ThreadLocal
1.ThreadLocal是什么
ThreadLocal 是一個(gè)創(chuàng)建線程局部變量的類(lèi)
通常我們創(chuàng)建的變量是可以被任何一個(gè)線程訪問(wèn)的,而使用 ThreadLocal 創(chuàng)建的變量只能被當(dāng)前線程訪問(wèn)晾浴,其他線程無(wú)法訪問(wèn)星岗。
2.ThreadLocal是如何確保只有當(dāng)前線程可以訪問(wèn)
我們先來(lái)分析一下ThreadLocal里面最重要的兩個(gè)函數(shù),get()
首有,set()
兩個(gè)函數(shù)燕垃。
public T get() {
//獲取當(dāng)前線程
Thread t = Thread.currentThread();
//利用當(dāng)前線程t來(lái)獲取當(dāng)前線程中的 threadLocals 變量
ThreadLocalMap map = getMap(t);
if (map != null) {
//利用當(dāng)前threadlocal作為key來(lái)獲取 ThreadLocalMap.Entry,其中就有保存的value
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
從get()
井联,set()
兩個(gè)函數(shù),不難發(fā)現(xiàn)卜壕,在給ThreadLocal去set值或者get值的時(shí)候都會(huì)先獲取當(dāng)前線程,然后使用線程去調(diào)用getMap(thread)
,getMap
返回的就是線程thread的成員變量threadLocals
烙常。所以這樣就保證了threadLocal的訪問(wèn)轴捎,一定是只能訪問(wèn)或修改當(dāng)前線程的值,這就保障了這個(gè)變量是線程的局部變量蚕脏。
ThreadLocalMap是什么
ThreadLocalMap是ThreadLocal的內(nèi)部類(lèi)侦副。
static class ThreadLocalMap {
/**
* The entries in this hash map extend WeakReference, using
* its main ref field as the key (which is always a
* ThreadLocal object). Note that null keys (i.e. entry.get()
* == null) mean that the key is no longer referenced, so the
* entry can be expunged from table. Such entries are referred to
* as "stale entries" in the code that follows.
*/
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
private Entry[] table;
}
從源碼可以看出來(lái)ThreadLocalMap中有一個(gè)數(shù)組table,數(shù)組里面是繼承自弱引用的Entry驼鞭。弱引用的使用也是為了當(dāng)出現(xiàn)異常情況秦驯,比如死循環(huán)的時(shí)候內(nèi)存能得到回收。Entry里面就保存了真實(shí)的白娘value挣棕,并且以threadlocal作為key译隘。所以相同類(lèi)型的threadLocal只能在線程中關(guān)聯(lián)一個(gè)實(shí)例。