聊聊ThreadLocal
聊聊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的四种引用方式。
- 点赞
- 收藏
- 关注作者
评论(0)