ThreadLocal类提供了线程本地变量访问的公共接口,每个线程通过ThreadLocal访问存储在线程本地的变量。当某个线程调用ThreadLocal的get或set方法时,ThreadLocal根据调用线程来获取或设置该线程的本地变量。这个变量存储在一个ThreadLocalMap的哈希表中,key为ThreadLocal对象,代表特定的变量,value就是本地变量值。因为每个线程只能访问自身本地内的变量,所以不存在线程安全问题。
public T get() {
Thread t = Thread.currentThread(); // 获取调用线程
ThreadLocalMap map = getMap(t); // 根据调用线程获取次线程的哈希表
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this); // this就是ThreadLocal对象,代表特定的本地变量
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue(); // 某个线程首次调用get方法,要执行初始化
}
ThreadLocalMap getMap(Thread t) {
// Thread类中有一个存储本地变量的哈希表:
// ThreadLocal.ThreadLocalMap threadLocals = null;
// 该哈希表中存储了不同的本地变量(通过不同的ThreadLocal对象)
return t.threadLocals;
}
private T setInitialValue() {
T value = initialValue(); // initialValue是protected方法,提供给子类重写,默认返回null
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) // 设置初始值
map.set(this, value);
else // 新建线程t中存储本地变量的哈希表
createMap(t, value);
return value;
}
void createMap(Thread t, T firstValue) { // 新建线程t中存储本地变量的哈希表
t.threadLocals = new ThreadLocalMap(this, firstValue); // this为ThreadLocal对象,代表某特定本地变量
}
public void set(T value) { // 设置当前线程本地变量值
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}