聊聊ThreadLocal

举报
周杰伦本人 发表于 2022/07/27 14:16:03 2022/07/27
1k+ 0 0
【摘要】 聊聊ThreadLocal java的四种引用 解决方案 总结 聊聊ThreadLocal今天我们聊聊ThreadLocal,虽然开发中用的比较少,但确是面试中经常会问到的点。每个线程都有个ThreadLocalMap,ThreadLocalMap是ThreadLocal的静态内部类,它的key是ThreadLocal的实例,value是需要存储的对象,而ThreadLocalMap其实是...

聊聊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的四种引用方式。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。