• 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原理

  • 相关阅读:
    剔除数组中重复对象
    2018湖南省高中数学联赛(A)试题
    向量与三角
    阿波罗尼斯圆
    2019高考理科数学(天津卷)
    转载Android常见错误(http://www.cnblogs.com/oklanyan/archive/2011/10/12/2208378.html)
    TCP/IP网络层谜云
    bitmap 设置图片尺寸,避免 内存溢出 OutOfMemoryError的优化方法(转载:http://tonyyu.iteye.com/blog/713256)
    ArcGIS for Android 离线数据编辑原理
    Android环境搭建(XP/Win7)转载http://www.cnblogs.com/oklanyan/archive/2011/10/14/2207339.html
  • 原文地址:https://www.cnblogs.com/yuyutianxia/p/3985207.html
Copyright © 2020-2023  润新知