InheritableThreadLocal使用與原始碼分析
阿新 • • 發佈:2019-01-02
InheritableThreadLocal使用
子執行緒需要獲取父執行緒中的ThreadLocal中的值的時候,使用InheritableThreadLocal
public class TestInheritableThreadLocal {
public static final SecureRandom random = new SecureRandom();
public static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
public static void main(String[] args) {
threadLocal.set(random.nextInt());
GetValThread thread = new GetValThread();
thread.start();
System.out.println("main----" + threadLocal.get());
}
static class GetValThread extends Thread {
@Override
public void run() {
System.out.println("local thread ----" + threadLocal.get());
}
}
}
執行結果如下:
main-----1845871892
local thread ----null
程式碼
public static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
修改為:
public static ThreadLocal<Integer> threadLocal = new InheritableThreadLocal<>();
執行結果如下:
main-----610914016
local thread -----610914016
InheritableThreadLocal原始碼分析
InheritableThreadLocal原始碼很簡單,重寫了ThreadLocal中“
public class InheritableThreadLocal<T> extends ThreadLocal<T> {
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獲取值的過程如下,從自己的ThreadLocalMap中取值。
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();
}
InheritableThreadLocal本身的ThreadLocalMap初始化在建立執行緒自己的時候,copy父執行緒的ThreadLocalMap,具體實現在Thread建構函式中,具體如下:
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) {
//省略上面部分程式碼
if (parent.inheritableThreadLocals != null)
//這句話的意思大致不就是,copy父執行緒parent的map,
//建立一個新的map賦值給當前執行緒的inheritableThreadLocals。
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
//ignore
}