唯一限定私有量 -- ThreadLocal

一:概述

首先搞清楚这个类作用在于为线程提供局部变量操作,其次就需要根据这个作用讨论它的实现原理以及一些可能出现的问题如内存泄漏等

二:ThreadLocalMap

ThreadLocal与ThreadLocalMap的关系我理解为包装袋与包装品的关系,ThreadLocal只是为其内部类ThreadLocalMap提供一层包装,撕开虚伪的面具,发现面具下隐藏就是ThreadLocalMap

2.1 重要属性

内部类ThreadLocalMap维护三个比较重要的属性,Entry数组table用于存储线程元素、size用于统计元素数量、threshold表示扩容阈值
在这里插入图片描述

2.2 Entry

一个线程元素set()存储时就会生成一个Entry实例存储到table数组中,Entry类是ThreadLocalMap的一个静态内部类。Object类型的属性value存储元素,使用ThreadLocal实例作为key,至于这里的弱引用效果在后面会详细解释
在这里插入图片描述

2.3 构造函数

初始化table数组默认容量为16、根据当前ThreadLocal对象经过哈希运算计算出数组中存储的下标、再实例化Entry对象并存储到table数组中、更改数量size与阈值threshold。其实从这里可以得出结论一个ThreadLocal实例只能操作存储一个线程局部变量,重复操作会覆盖元素
在这里插入图片描述

三:元素存储示意图

在这里插入图片描述

四:元素存储源码解析

比较简单的一个set()方法,其中的重点在于以下两点:

  • 线程怎么维护与ThreadLocalMap的关系
  • ThreadLocalMap中如何存储线程局部变量

在这里插入图片描述

4.1 线程与ThreadLocalMap

图一表示set()方法中的getMap()方法,根据当前线程获取ThreadLocalMap实例。再一看原来是Thread类中维护了ThreadLocalMap的实例变量属性threadLocals,这就解决了通过线程获取ThreadLocalMap实例的问题
在这里插入图片描述
在这里插入图片描述

4.2 首次存储

首次存储也就是通过当前线程获取ThreadLocalMap实例的时候返回值为null,这时候调用createMap()创建一个ThreadLocalMap实例并赋值给线程实例属性threadLocals。再这里建议回头再看一下ThraedLocalMap前面提到的带参构造函数
在这里插入图片描述

4.3 再次存储

再次存储也就是当调用ThreadLocal方法set()时获取当前线程已经存在ThreadLocalMap实例,这时候就会往这个ThreadLocalMap中存储新的元素。前面在谈ThreadLocalMap构造函数的时候就说过操作同一个ThreadLocal只能存储一个局部变量,在这里调用ThreadLocalMap的set()方法就可以印证上述结论,注意选中区域。遍历table数组查看key即ThreadLocal实例是否一致,若一致则覆盖value
在这里插入图片描述

五:元素获取

根据存储流程其实不用看ThreadLocal的get()实现大概都能知悉它的操作

  • 根据当前线程获取theadLocals即ThreadLocalMap实例
  • 根据当前ThreadLocal实例计算数组下标index
  • 根据下标index获取Entry实例并比较key是否为当前ThreadLocal实例返回元素值

在这里插入图片描述

5.1 未存先取

当前线程并未存储局部变量即线程属性threadLocals为空的情况称之为未存先取,这时候调用方法setInitiaValue(),进入方法后的逻辑相当简单,与首次存储的逻辑一致。只不过这里的value是null,不清楚可以回头看看首次存储的描述

六:key回收

不论是在元素存储亦或是元素获取时都会判断Entry实例的key == null的情况,key不是ThreadLocal实例么?怎么可能等于null呢?请回头看我已经着重提醒那是一个弱引用,Java四大引用类型中的弱引用表示当内存不足发生GC时就会被回收的内存区域。如下图所示,key为弱引用,但是value是与当前线程组成一条强引用链,也就可能出现key被回收为null,但是value未被回收。如果线程久久不结束导致内存区域无法回收还会导致内存泄漏的情况产生
在这里插入图片描述

七:多变量维护

正如前面所言一个ThreadLocal实例只能维护一个线程局部变量
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值