目录
1.简介
2.使用
3.源码分析
3.1.1 ThreadLocal
3.1.2 InheritableThreadLocal
3.1.3Thread.init()
4.总结
InheritableThreadLocal作为ThreadLocal的扩展,本身要达到的目的依然是线程局部数据的存储,功能完全等同ThreadLocal,并在其基础上增加了父子线程减数据传递的功能,使用了Thread的另一个变量
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
在new Thread(Runnable)的时候,会执行init初始化方法,进而将父线程的inheritableThreadLocals数据传递给子线程,详见源码分析第三节。
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
上篇我们分析了ThreadLocal,点击详细
这里我们着重分析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()时会根据条件初始化该变量
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++; } } } }
简单明了,但是现目前的项目中,我们更多的使用的是线程池,故而其使用场景不是特别广泛。