InheritableThreadLocal<T>
InheritableThreadLocal<T> 类是 ThreadLocal<T> 类的子类,译为可继承的 ThreadLocal。
public class InheritableThreadLocal<T> extends ThreadLocal<T> {
childValue(T)
在 ThreadLocal 类中直接抛出一个 UnsupportedOperationException 异常,在本类中直接返回 T 类型的参数,感觉在本类的子类中才会有意义。
只在 ThreadLocalMap(ThreadLocalMap) 中被调用。
protected T childValue(T parentValue) {
return parentValue;
}
getMap(Thread)
获得 Thread 类型参数的 ThreadLocal.ThreadLocalMap 类型的 inheritableThreadLocals 域。
ThreadLocalMap getMap(Thread t) {
return t.inheritableThreadLocals;
}
createMap(Thread, T)
和 getMap 方法一样,就是把 ThreadLocal 类的方法中的 threadLocals 替换为 inheritableThreadLocals。
void createMap(Thread t, T firstValue) {
t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
}
Thread.init(ThreadGroup, Runnable, String, long, AccessControlContext, boolean)
当参数 inheritThreadLocals 为 true 且正在构造的 Thread 类的父线程的 inheritableThreadLocals 不为空,调用 ThreadLocal 类的静态方法 createInheritedMap 初始化正在构造的 Thread 类的 inheritableThreadLocals 域。
只在 Thread(Runnable target, AccessControlContext acc) 中被调用时参数 inheritThreadLocals 为 false,在其它地方被调用时为 true。
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);
...
}
ThreadLocalMap(ThreadLocalMap)
初始化 threshold 域和 table 域,threshold 域为 ThreadLocalMap 类型的参数 parentMap 的 table 域的长度的三分之二,table 域为参数 parentMap 的 table 域的浅拷贝。实现了父子线程局部变量的传递,但是之后父子线程的局部变量除了 ThreadLocal 对象变为 null 的情况外互不影响。
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++;
}
}
}
}