这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
概述
每个Thread维护一个ThreadLocalMap,这个Map的key是ThreadLocal实例对象本身,value才是真正要春初的值Object。
- 每个ThreadLocal线程内部都有一个map(ThreadLocalMap)
- Map里面存储ThradLocal对象(Key)和线程的变量副本(Value)
- Thread内部的Map是由ThreadLocal维护的,由ThreadLocal负责向map获取和设置线程的变量值。
- 对于不同的线程,每次获取副本值时,别的线程并不能获取到当前现场的副本值,形成了副本的隔离,互不干扰。
ThreadLocal内部方法以及内部类
内部的方法的实现
| 方法声明 | 描述 |
|---|---|
| ThreadLocal() | 创建ThreadLocal |
| public void set() | 设置当前线程绑定的变量 |
| public T get() | 获取当前线程绑定的变量 |
| public void remove() | 移除当前线程绑定的变量 |
ThreadLocal对外提供了四个方法,接下来一个个去分析。
1.set()
/**
* 设置当前线程对于的ThreadLocal的值
*
* @parameter value 将要保存在当前线程对应的ThreadLocal的值
*/
public void set(T value) {
//获取当前线程
Thread t = Thread.currentThread();
//获取当前线程对象中维护的ThradLocalMap对象
ThreadLocalMap map = getMap(t);
if (map != null)
//set设置此实体的entry,以当前ThreadLocal为key
map.set(this, value);
else
//1.当前线程,不存在ThreadLocalMap对象
//2.调用createMap进行ThreadLocalMap对象的初始化
//3.将当前线程和value作为第一个entry存放到ThreadLocalMap中
createMap(t, value);
}
/**
* 设置当前线程对应的ThreadLocalMap
*
* @parameter t 当前线程
*/
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
/**
* 创建当前线程所对应的ThreadLocalMap
* Thread里所维护的threadLocals是在这里所进行的初始化
*
* @param t the current thread
* @param firstValue 存放map中第一个entry的值
*/
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
//Thread里各自维护了一个ThreadLocalMap的实例对象
set()执行流程
- 首先获取当前程序,并根据当前线程获取一个map
- 如果获取的Map不为空,则将参数设置到map。(ThreadLocal作为key)
- 如果map为空,则给该线程创建Map,并设置初始值,完成Thread里维护的ThreadLocalMap的初始化
2.get()
/**
* 返回当前线程中保存的以ThreadLocal为key所对应的value
* 如果没有此Key,通过调用SuppliedThreadLocal.initialValue()进行初始化
*/
public T get() {
//获取当前线程
Thread t = Thread.currentThread();
//获取当前线程维护的ThradLocalMap
ThreadLocalMap map = getMap(t);
if (map != null) {
//以当前ThradLocal作为key,调用getEntry获取存储实体
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
//get value
T result = (T)e.value;
return result;
}
}
// map不存在或者map存在但是没有与 当前ThreadLocal关联的entry
// 初始化map
return setInitialValue();
}
/**
* 初始化ThreadLocalMap
*/
private T setInitialValue() {
//获取初始化的值,可被子类重写,如果不重写的话默认返回null
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
get()执行流程
- 获取当前线程的ThreadLocalMap
- map != null? 获取map中对于的Entry : initialValue()获取初始值,然后初始化map
- 如果map.getEntry(this)不为null,返回value