ThreadLocal如何在子线程传递

主线程如何向自己创建的子线程传递ThreadLocal值,只需要创建InheritableThreadLocal值,实现原理如下:

InheritableThreadLocal覆写了它三个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class InheritableThreadLocal<T> extends ThreadLocal<T> {

//创建线程时候,会调用该方法,见下面init
protected T childValue(T parentValue) {
return parentValue;
}

//获取Map时候,返回的是t.inheritableThreadLocals,见ThreadLocal操作值
ThreadLocalMap getMap(Thread t) {
return t.inheritableThreadLocals;
}

//createMap时候,返回的是t.inheritableThreadLocals,见ThreadLocal操作值
void createMap(Thread t, T firstValue) {
t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
}
}

见子线程初始化过程,初始化时候如果当前线程inheritableThreadLocals不为空

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
//......
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
//这里初始的是this.inheritableThreadLocals
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
//......
}

// ThreadLocal.createInheritedMap会调用ThreadLocalMap(ThreadLocalMap parentMap)方法,
private ThreadLocalMap(ThreadLocalMap parentMap) {
Entry[] parentTable = parentMap.table;
int len = parentTable.length;
setThreshold(len);
table = new Entry[len];

for (int j = 0; j < len; j++) {
Entry e = parentTable[j];
if (e != null) {
@SuppressWarnings("unchecked")
ThreadLocal<Object> key = (ThreadLocal<Object>) e.get();
if (key != null) {
//这里调用InheritableThreadLocal覆写的childValue,返回的是parent的value,将parent的值copy到子线程中
Object value = key.childValue(e.value);
Entry c = new Entry(key, value);
int h = key.threadLocalHashCode & (len - 1);
while (table[h] != null)
h = nextIndex(h, len);
table[h] = c;
size++;
}
}
}
}

那么inheritableThreadLocals它什么时候不为空呢,见下面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//在set值时候判断ThreadLocalMap为空,调用InheritableThreadLocal.getMap方法返回当前线程的t.inheritableThreadLocals,否则初始化t.inheritableThreadLocals
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}

//获取的是t.inheritableThreadLocals的值
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();
}

//删除值实际上删除的t.inheritableThreadLocals
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}