InheritableThreadLocal

InheritableThreadLocal是如何在子线程中获取到父线程中的值的?

在线程new Thread的时候,相关代码如下:

protected void init(......){
    ... ...
    //如果父线程有可继承的线程本地变量,就将其复制到本线程的inheritableThreadLocals中
    if (inheritThreadLocals && parent.inheritableThreadLocals != null)
                this.inheritableThreadLocals =
                    ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
    ... ...
}

具体的复制逻辑为:

static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
        return new ThreadLocalMap(parentMap);
}

//创建threadlocalmap(每个线程都维护一个ThreadLocalMap,key为ThreadLoca,value为具体的值)
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++;
                }
            }
        }
}

而具体InheritableThreadLocal的代码则非常简洁:

因为父线程的值的copy逻辑都是在new子线程的时候,线程初始化时完成的。

整个逻辑为:

①Thread类内部维护一个inheritableThreadLocals变量

②某Thread初始化时,判断父线程中的inheritableThreadLocals中有无线程本地变量,有则复制到该线程中的inheritableThreadLocals变量中。

③InheritableThreadLocal类重写了getMap方法,使其返回线程的inheritableThreadLocals变量,这样在get的时候,是从该key-value中获取。

Last updated