目录
1.简介
InheritableThreadLocal作为ThreadLocal的扩展,本身要达到的目的依然是线程局部数据的存储,功能完全等同ThreadLocal,并在其基础上增加了父子线程减数据传递的功能,使用了Thread的另一个变量
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
在new Thread(Runnable)的时候,会执行init初始化方法,进而将父线程的inheritableThreadLocals数据传递给子线程,详见源码分析第三节。
2.使用
demo
public class MyThread_localThreadTest {
public static ThreadLocal<String> threadLocal = new ThreadLocal<>();
public static ThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();
public static void main(String[] args) {
threadLocal.set("threadLocal 的值: hello threadLocal");
inheritableThreadLocal.set("inheritableThreadLocal 的值: hello inheritableThreadLocal");
new Thread(()-> {
System.out.println("子线程获取到的值--threadLocal:" + threadLocal.get());
System.out.println("子线程获取到的值--inheritableThreadLocal:" + inheritableThreadLocal.get());
System.out.println("==================================");
new Thread(()->{
System.out.println("孙子线程获取到的值--threadLocal:" + threadLocal.get());
System.out.println("孙子线程获取到的值--inheritableThreadLocal:" + inheritableThreadLocal.get());
}).start();
}).start();
}
}
输出:
子线程获取到的值--threadLocal:null
子线程获取到的值--inheritableThreadLocal:inheritableThreadLocal 的值: hello inheritableThreadLocal
==================================
孙子线程获取到的值--threadLocal:null
孙子线程获取到的值--inheritableThreadLocal:inheritableThreadLocal 的值: hello inheritableThreadLocal
3.源码分析
3.1.1 ThreadLocal
上篇我们分析了ThreadLocal,点击详细
这里我们着重分析InheritableThreadLocal
3.1.2 InheritableThreadLocal
public class InheritableThreadLocal<T> extends ThreadLocal<T> {
@Override
protected T childValue(T parentValue) {
return parentValue;
}
@Override
ThreadLocalMap getMap(Thread t) {
return t.inheritableThreadLocals;
}
@Override
void createMap(Thread t, T firstValue) {
t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
}
}
InheritableThreadLocal重写了ThreadLocal的getMap(),createMap()方法,转而使用了新的变量,而在new Thread()时会根据条件初始化该变量
3.1.3Thread.init()
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);
继续跟踪ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
return new ThreadLocalMap(parentMap);
}
而new 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) {
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++;
}
}
}
}
4.总结
简单明了,但是现目前的项目中,我们更多的使用的是线程池,故而其使用场景不是特别广泛。