写点什么

聊聊 ThreadLocal

作者:周杰伦本人
  • 2022-11-20
    山东
  • 本文字数:1015 字

    阅读完需:约 3 分钟

聊聊 ThreadLocal

今天我们聊聊 ThreadLocal,虽然开发中用的比较少,但确是面试中经常会问到的点。


每个线程都有个 ThreadLocalMap,ThreadLocalMap 是 ThreadLocal 的静态内部类,它的 key 是 ThreadLocal 的实例,value 是需要存储的对象,而 ThreadLocalMap 其实是用 Entry 数组存储的,Entry 继承 WeakReference,它是一个弱引用。


static class Entry extends WeakReference<ThreadLocal<?>> {            /** The value associated with this ThreadLocal. */            Object value;
Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } }
复制代码


这里需要普及一下 java 的四种引用

java 的四种引用

强引用:像通过 new 对象就是强引用,这一般不会被 GC 回收


软引用:内存不够的时候才会进行内存回收,


弱引用:不管内存够不够用,垃圾回收器在进行回收的时候都会进行内存回收,一般是弱引用在 map 中使用


虚引用:在任何时候都可能被回收


TheadLocal 是线程私有的,线程之间不受影响,所以可以保证线程安全的问题,当我们跨层传递的时候可以考虑使用 ThreadLocal,spring 的事务信息就是放在 ThreadLocal 中的


但是大家都知道,ThreadLocal 存在内存泄露的问题,所谓内存泄露就是不再使用的对象占用的内存不能够被回收,new 对象就有可能导致内存泄露,当 ThreadLocal 不存在强引用的时候,ThreadLocalMap 的 key 就会被回收,这时候 key 为 null,此时的 value 却是强引用,那么此时只有当前线程的中断或结束的时候,ThreadLocalMap 中的数据才会被清空,如果当前线程一直在运行,显然 value 不能被回收,就产生了内存泄露。而当 key 为空的时候,调用 ThreadLocalMap 的 get 方法或者 set 方法或者 remove 方法的时候都会清除 value 值

解决方案

解决办法呢就是当我们 ThreadLocal 使用完毕后,通过调用 ThreadLocal 的 remove 方法来进行清除数据,也可以把 ThreadLocal 设置为 private static,这样 ThreadLocal 就是强引用了,这样 TheadLocalMap 的 key 就不会为 null,从而在适当的时候就清理掉数据了。

总结

这篇文章主要讲了 hreadLocal 的相关知识点,包括为什么出现内存泄露的问题,已经对于这种问题的解决方案,并顺带讲了一下 java 的四种引用方式。

❤️ 感谢大家

如果你觉得这篇内容对你挺有有帮助的话:


  1. 欢迎关注我❤️,点赞👍🏻,评论🤤,转发🙏

  2. 关注盼盼小课堂,定期为你推送好文,还有群聊不定期抽奖活动,可以畅所欲言,与大神们一起交流,一起学习。

  3. 有不当之处欢迎批评指正。

发布于: 刚刚阅读数: 4
用户头像

还未添加个人签名 2020-02-29 加入

公众号《周结论本人》,多平台优质博主

评论

发布
暂无评论
聊聊ThreadLocal_11月月更_周杰伦本人_InfoQ写作社区