ThreadLocal源码分析

1.基本介绍

        (1)每一个Thread里面有一个ThreadLocalMap对象,里面可以存储ThreadLocal(hashcode是重写的,使用的是黄金分割数,目的是为了让他在ThreadLocalMap中分布的更均匀)为key,set的数据为value放入ThreadLocalMap中

        (2)ThreadLocal本身体是强引用,但是作为ThreadLocalMap的Entry的key时候,会继承弱引用,当ThreadLocal的实例数据被强引用释放时,Entry还会弱引用这个实例对象,不过随时会被GC回收掉

        (3)当key被GC之后就变成了null,若不及时的remove 就会造成value永久存在从而造成数据泄露,另外在线程池中的线程也遵从1,2若不及时存储,就有可能造成脏数据,简简单单的存放获取新数据没什么问题,假如直接获取数据的话就会出现安全问题

2.ThreadLocal   set方法

set方法被调用时候,会获取set运行的线程中的ThreadLocalMap对象

       1.如果不是空的话就将value设置到Map

       2.如果是空

 就创建一个ThreadLocalMap对象,创建容量为16的Entry数组,设置length*2/3的阈值,size+1,并赋值给Thread的threadLocals引用上,并将要set的value 放入map中

Thread中的ThreadLocalMap是懒初始化,

A,ThreadLocalMap的set方法过程如下

     1.&到的下标所对应的Entry为空,

           直接包装value到Entry中插入到该下标

     2.该下标的Entry不是空,

            Entry的key跟要set的key相同,直接更新当前Entry的value

     3.下标的Entry不是空,但Entry的key是null(假定当前位置是staleSlot)

         A。staleSlot所对应的Entry的key为null

         B,从staleSlot的下标位置往前找,直到Entry为null,将距离Entry为null最近且key为null的过期数据的下标,记录到slotToExpunge(如果没找到的话 slotToExpunge 还是staleSlot)

        C,从staleSlot的下一个往后找,直到找到的Entry是null,(有可能碰到key为null,或者匹配的key)

                (1)Entry数据 key匹配  交换当前位置与staleSlot数据的位置,并开始执行清理过期数据

                (2)发现了第一个key为null的过期数据,将slotToExpunge指定到当前下标

        D.找到最后也没发现key=null或者key相等的Entry,将staleSlot对应的数据的valueGc掉,同时,包装当前value到Entry中插入到staleSlot的下标中

        E.  D C(1)步骤均需要清理过期数据

              a.清理当前下标的数据,并向后遍历知道entry为null

              c.当前entry是过期数据,直接置为null

              d.不是过期数据,计算应该所在的index下标位置,然后从index往后查,如果查到一个过期的数据temp的话,直接将当前entry的数据更新到  temp所对应的下标去

              e.从a遍历的最后一个entry为null的下标i,往后接着尝试(次数为length最高位右移的位数)遍历 如果发现为过期数据的话走a,尝试最多次数后放弃

     4..如果下标的Entry不是空,并且key不等,那么向后寻址,继续1.2的步骤

     5.如果清理完过期的数据之后size还大于四份之三的阈值的话就会扩容

          a。数组为原来的2倍,重新设定阈值

          c.拷贝数据到新数组,有hash 碰撞的数据的话切不过期的话就往后面插入,过期的话直接释放

 B。get方法

     1.如果当前Thread的ThreadLocalMap还没有被初始化那么直接调用setInitialValue的方法

会先调用自身的initialValue方法,创建好Map之后返回当前value(initialValue产生的)

     

2.如果map不是null ,就调用getEntry的方法获取到,如果getEntry也没找到,就调用setInitialValue的放法

每一次的setget remove都会清理过期数据,并将过期数据的位置替换成本该自己的位置 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值