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
}