這是兩個很基礎的類了,大多數情況下都會用到。今天在羣裏有人說到這個問題,我順便就看了下源碼。
這裏就簡單說下這兩個類的關係吧。
我們知道,在多線程環境下每個 Thread 的 ThreadLocal 是隔離的,每個 Thread 都擁有自己的 ThradLocal 副本。
換個說法就是通過同一個 ThreadLocal 在多線程的環境下可以存放和獲取不同的值。
從 ThreadLocal 的 get 方法入手,看看數據是從哪裏取的
public class ThreadLocal<T> {
...
/**
* 這裏的 getMap 方法獲取存有數據的map,並且key爲當前線程
*/
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對應 threadLocals 屬性
*/
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
...
}
public
class Thread implements Runnable {
...
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class.
* 這裏看到上面 ThreadLocal 存放數據的map來自 Thread 的 threadLocals,並且該map由 ThreadLocal 維護
*/
ThreadLocal.ThreadLocalMap threadLocals = null;
...
}
這裏我們可以梳理下這兩者的關係:
1、Thread 擁有屬於自己的一個map,key爲 ThreadLocal,value爲值
2、ThreadLocal 獲取值時實際上是從當前 Thread 的map中獲取(以自己爲key)
這也就是爲什麼 ThreadLocal 能在每個 Thread 中保持一個副本,實際上數據是放在 Thread 中的。