为什么TheadLocalMap设计成一个个entry对象,而不用hashMap?

1、在设计ThreadLocal时,参考jdk都是鉴于效率性能优先。ThreadLocalMap对ThreadLocal场景做了优化,这些场景是特定的,而不一定适用于原先的hashMap适用的场景。

ThreadLocalMap是由一个个Entry键值对组成,key是ThreadLocal对象,value为线程变量的副本。每一个Thread都有一个ThreadLocalMap 类型的成员变量 threadLocals ,它存储本线程中所 有ThreadLocal对象及其对应的值。并且他是一个WeakReference 弱引用,当没有指向key的强引用后,该key就会被垃圾回收器回收。如果不是弱引用,那么因为这个 Map 的强引用导致这个线程的 ThreadLocalMap 对应的 ThreadLocal key 一直不能被回收。

2、减少哈希碰撞,如果你的程序需要多个 ThreadLocal,并且每个线程都使用了 这些 ThreadLocal。 Entry[] table 的大小一直是 2 的 n 次方,这样根据 Hash 值放入的时候,取余变成对于 2 的 n 次方 -1 取与运算。Hash 值计算是开放地址法,每新建一个 ThreadLocal 则将全局的 nextHashCode + 0x61c88647,这个魔法数保证了大部分情况下无论 Entry[] table 扩容到什么程度,都可以保证生成的 Hash 值 对于目前 table 大小的值 - 1 取与运算落入尽量不同的位置,减少哈希碰撞,增加效率。

那如果ThreadLocal发生内存泄漏,原因一定是弱引用吗?

ThreadLocal发生内存泄漏的关键在于,ThreadLocalMap和Thread有相同的生命周期,当外部没有强引用指向ThreadLocal时,在ThreadLocalMap里面的key就会被移除,而value还存在着强引用,只有当Thread退出线程后,value的强引用才会断,如果线程一直不结束的话,j这些key为null的Entry的value就会一直存在一条强引用链。

 

ThreadLocal正确的使用方法

每次使用完ThreadLocal都调用它的remove()方法清除数据。

将ThreadLocal变量定义成private static,这样就一直存在ThreadLocal的强引用,也就能保证任 何时候都能通过ThreadLocal的弱引用访问到Entry的value值,进而清除掉 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今天你学习了ma

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值