在上一篇Java ThreadLocalMap 源码解析的基础上,本文开始分析ThreadLocal相关源码。
参照下方UML图,可以看出:
1)Thread类关联ThreadLocalMap对象,分别对应成员变量threadLocals和inheritableThreadLocals;
2)ThreadLocal依赖Thread对象,主要表现为操作Thread对象的ThreadLocalMap对象;
3)InheritableThreadLocal类继承ThreadLocal类,主要用于实现子线程继承父线程的ThreadLocalMap对象inheritableThreadLocals。
如下源码,Thread的构造器方法全部调用了init方法。其中第三个构造器最后一个参数false表示不继承父线程的ThreadLocalMap对象,其余构造器全部默认继承父线程的ThreadLocalMap对象。
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
Thread(Runnable target, AccessControlContext acc) {
init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
}
public Thread(ThreadGroup group, Runnable target) {
init(group, target, "Thread-" + nextThreadNum(), 0);
}
public Thread(String name) {
init(null, null, name, 0);
}
public Thread(ThreadGroup group, String name) {
init(group, null, name, 0);
}
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
public Thread(ThreadGroup group, Runnable target, String name) {
init(group, target, name, 0);
}
public Thread(ThreadGroup group, Runnable target, String name,
long stackSize) {
init(group, target, name, stackSize);
}
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* InheritableThreadLocal values pertaining to this thread. This map is
* maintained by the InheritableThreadLocal class.
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null, true);
}
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
/*** 为了强调本文描述重点,此处省略部分代码 ***/
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
/* Set thread ID */
tid = nextThreadID();
}
结合上述代码,当一个线程创建后,成员变量threadLocals为空,成员变量inheritableThreadLocals则根据是否继承父线程inheritableThreadLocals判断逻辑初始化。
ThreadLocalMap类是ThreadLocal类的内部静态类。分析完ThreadLocalMap源码后,再分析ThreadLocal源码,就简单许多了。
set方法的作用是将传参设置到当前线程的成员变量threadLocals中。如果成员变量threadLocals为空,则调用creaeMap方法新建。
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
get方法从当前线程的成员变量threadLocals中获取当前ThreadLocal作为Key对应Entry的Value,如果threadLocals为空,或未找到,则返回初始值(可重写,默认为空)。
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();
}
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
protected T initialValue() {
return null;
}
从当前线程成员变量threadLocals中删除当前ThreadLocal作为Key对应Entry。
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
public class InheritableThreadLocal extends ThreadLocal {
protected T childValue(T parentValue) {
return parentValue;
}
ThreadLocalMap getMap(Thread t) {
return t.inheritableThreadLocals;
}
void createMap(Thread t, T firstValue) {
t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
}
}
InheritableThreadLocal类继承ThreadLocal类。需要强调的是,childValue方法用于继承父线程inheritableThreadLocals时,以什么形式复制其中的值,默认为直接返回父线程inheritableThreadLocals中Entry的Value值。
结合以上分析,ThreadLocal和InheritableThreadLocal主要用于变量在线程间共享,并不能解决线程安全问题,原因是其变量共享方式为潜拷贝。