(一)ThreadLocalMap

   ThreadLocalMap是定义在ThreadLocal中的静态类

static class ThreadLocalMap {

        //key一定是ThreadLocal类型的对象,如果key为空,则该Entry被视为不新鲜的Entry,不再被引用,即可以从table列表中删除
        static class Entry extends WeakReference<ThreadLocal<?>> {
            //值
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }

        //table列表的初始容量
        private static final int INITIAL_CAPACITY = 16;

        //table列表
        private Entry[] table;

        //table列表中的元素个数
        private int size = 0;

        //重哈希的阈值
        private int threshold; // Default to 0

        //设置重哈希的阈值
        private void setThreshold(int len) {
            threshold = len * 2 / 3;
        }

        //索引位置循环向后移动
        private static int nextIndex(int i, int len) {
            return ((i + 1 < len) ? i + 1 : 0);
        }

        //索引位置循环向前移动
        private static int prevIndex(int i, int len) {
            return ((i - 1 >= 0) ? i - 1 : len - 1);
        }

        //构造方法
        ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
            //初始化table列表
            table = new Entry[INITIAL_CAPACITY];
            //确定下标
            int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
            //元素赋值
            table[i] = new Entry(firstKey, firstValue);
            //元素个数
            size = 1;
            //设置重hash阈值
            setThreshold(INITIAL_CAPACITY);
        }

        //构造方法
        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++;
                    }
                }
            }
        }
}
10-12 02:44