ThreadLocal(四) : FastThreadLocal原理

一、ThreadLocal的原理以及存在的问题

a. 每个线程内部维护了一个ThreadLocal.ThreadLocalMap类型的变量

b. ThreadLocalMap 的 key 为 ThreadLocal,value为对应的变量

c. 对ThreadLocal进行get/set操作时,会先获取当前Thread内部的ThreadLocal.ThreadLocalMap,然后以ThreadLocal为key,从这个Map中获取对应的value

设计理念:

a. ThreadLocal中的数据实际存放于Thread中,线程死亡时,这些数据会被自动释放,减小了开销

b. 一般来说,一个ThreadLocal对应的Thread数量远多于一个Thread所对应的ThreadLocal数量,因此Thead内部维护的ThreadLocal.ThreadLocalMap的长度一般来说是较短的,寻址快速

 

1. ThreadLocal#get的问题

 /**
         * Get the entry associated with key.  This method
         * itself handles only the fast path: a direct hit of existing
         * key. It otherwise relays to getEntryAfterMiss.  This is
         * designed to maximize performance for direct hits, in part
         * by making this method readily inlinable.
         *
         * @param  key the thread local object
         * @return the entry associated with key, or null if no such
         */
        private Entry getEntry(ThreadLocal<?> key) {
            int i = key.threadLocalHashCode & (table.length - 1);
            //ThreadLocal的threadLocalHashCode是在定义ThreadLocal时产生的一个伪随机数
            Entry e = table[i];
            if (e != null && e.get() == key)
                return e;
            else
                return getEntryAfterMiss(key, i, e);
        }

        /**
        * 使用线性探测法处理未命中的情况
     * 在未命中的情况下,可能会退化到O(n)的时间复杂度
        */
        private Entry getEntryAfterMiss(ThreadLocal<?> key, int i, Entry e) {
            Entry[] tab = table;
            int len = tab.length;

            while (e != null) {
                ThreadLocal<?> k = e.get();
                if (k == key)
                    return e;
                if (k == null)
                    expungeStaleEntry(i);//由于ThreadLocalMap中的Entry扩展于WeakReference,设置为null,方便回收
                else
                    i = nextIndex(i, len);//查找ThreadLocalMap中的下一个元素,直到命中为止(线性探测法)
                e = tab[i];
            }
            return null;
        }

 

 

 

二、FastThreadLocal


 FastThreadLocal的构造方法中,会为当前FastThreadLocal分配一个index,这个index是由一个全局唯一的static类型的AtomInteger产生的,可以保证每个FastThreadLocal的index都不同

 

参考:

ThreadLocal原理

posted @ 2014-09-21 23:42  等风来。。  Views(807)  Comments(0Edit  收藏  举报
------------------------------------------------------------------------------------------------------------ --------------- 欢迎联系 x.guan.ling@gmail.com--------------- ------------------------------------------------------------------------------------------------------------