聊聊ThreadLocal

151 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

聊聊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. 有不当之处欢迎批评指正。