深入理解ThreadLocal及其弱引用

深入理解ThreadLocal及其弱引用

早期版本中:

ThreadLocalMap是ThreadLocal的静态内部类,ThreadLocalMap的所有者是ThreadLocal。

ThreadLocalMap表中Entry的key为Thread实例。

所以就类似于ThreadLocal维护了所有线程的本地变量。但是这样会导致,ThreadLocalMap中有大量Entry。因为ThreadLocal是强引用,所以如果删除线程,对应的ThreadLocalMap不会被删除。导致内存挤压。

因此在JDK1.8之后:

ThreadLocalMap的所有者改为Thread。每一个Thread实例拥有一个ThreadLocalMap对象。

因为每一个Thread实例拥有一个ThreadLocalMap对象,所以如果删除线程,对应的ThreadLocalMap会随之销毁。同时也减少了ThreadLocalMap中Entry的数量。

至此早期版本存在的问题得到解决。下面是弱引用的问题。

ThreadLocalMap表中Entry的key为ThreadLocal实例,由ThreadLocal向map获取和设置线程变量值。(见下图,来源:极客时间)

因为ThreadLocal是Java对象,存放在堆中。所以Thread和ThreadLocalMap访问ThreadLocal是强引用。如果Thread不访问ThreadLocal对象,则强引用消失。value是存储的局部变量,根据存储需求变化,由用户而不由程序员控制。所以在下一次垃圾回收时 key 会被清理掉,而 value 不会被清理,value 的回收取决于 Thread 对象的生命周期。

如果是ThreadLocalMap的Entry是强引用:那么,在Thread不访问ThreadLocal对象之后,在下一次垃圾回收时,对应的ThreadLocal对象依然存在。如果是ThreadLocalMap的Entry是弱引用:那么,在Thread不访问ThreadLocal对象之后,在下一次垃圾回收时,对应的ThreadLocal对象会被自动清理。

但是,value不会随着ThreadLocal对象清理而被销毁。所以需要及时的remove()操作来减少空间浪费。

不过,这就意味着使用完 ThreadLocal , CurrentThread 依然运行的前提下。就算忘记调用 remove 方法,弱引用比强引用可以多一层保障:弱引用的 ThreadLocal 会被回收.对应value在下一次 ThreadLocaIMap 调用 set/get/remove 中的任一方法的时候会被清除,从而避免内存泄漏。

参考资料:https://blog.csdn.net/bbscz007/article/details/105686382黑马程序员讲ThreadLocal(2020年)极客时间JUC入门与进阶专栏

相关推荐

2026美加墨世界杯筹备加速,赛事看点与经济隐忧并存
2025 年活动健身追踪器热门精选
365天免费观看完整版电影

2025 年活动健身追踪器热门精选

📅 09-05 👁️ 6091
最近特别火的五部电视剧,《在人间》排在第二,第一排它毋庸置疑