Thread 的threadLocals 和 inheritableThreadLocals

两者什么差异呢,咱们来看下源码中的官方注释?


/* ThreadLocal values pertaining to this thread. This map is maintained

* by the ThreadLocal class. */

ThreadLocal.ThreadLocalMap threadLocals =null;
/*

    * InheritableThreadLocal values pertaining to this thread. This map is

    * maintained by the InheritableThreadLocal class.

    */

    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;


都是Thread的变量,看着是不是几乎一样. 正如inheritableThreadLocals 变量比threadLocals名称多的inheritable.
这里inheritableThreadLocals是可继承的.
这是什么意思呢?:
1)我們知道threadLocals 是线程独有的,也就是线程安全的.我们可将对线程安全 有要求的对象存在这里备用.
2)但是这里使用inheritableThreadLocals,a继承b,则a线程内部的inheritableThreadLocals会持有b中的值.

如何使用呢?
1)我们首先,针对threadLocals 和inheritableThreadLocals, 有两个类:ThreadLocal 和InheritableThreadLocal
2)之前如何使用,将其替换就可以
Thread-A:
ThreadLocal threadLocal  = new new ThreadLocal(); //使用ThreadLocal的方式
Thread-B:
ThreadLocal threadLocal  = new new InheritableThreadLocal ();//使用InheritableThreadLocal的方式

这个能力是如何实现的呢?
这个我们要看构造Thread的时候做了什么
//Thread
private void init(ThreadGroup g, Runnable target, String name,

                      long stackSize, AccessControlContext acc,

                      boolean inheritThreadLocals) {

      ........

        if (inheritThreadLocals && parent.inheritableThreadLocals != null) //这里inheritThreadLocals 一直是true

            this.inheritableThreadLocals =

                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); //这里是关键

      ......

}
ThreadLocal.createInheritedMap 又做了什么呢?

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 key = (ThreadLocal) 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++;

                    }

                }

            }

        }
我们看到所有的数值parentMap的值copy了一份到当前的线程table中,我们取得时候回去这里取:
private Entry getEntry(ThreadLocal key) {

            int i = key.threadLocalHashCode & (table.length - 1);

            Entry e = table[i];

            if (e != null && e.get() == key)

                return e;

            else

                return getEntryAfterMiss(key, i, e);

        }


其实用的时候,就当做一个普通陌生的黑盒使用就好

你可能感兴趣的:(Thread 的threadLocals 和 inheritableThreadLocals)