ThreadLocal是什么
官方解释:
- ThreadLocal是一个关于创建线程局部变量的类,主要作用是存储线程的局部变量,做到数据隔离。保存在ThreadLocal中的数据只属于当前线程,对其他线程是不可见的。在多线程环境下,可以防止自己的变量被其他线程修改而导致数据不一致性。
- ThreadLocal设计的目的就是为了能够使得当前线程拥有属于自己的变量,并不是为了解决并发或者共享变量的问题
- 底层使用ThreadLocalMap实现,每个线程都拥有自己的ThreadLocalMap,内部是继承了WeakReference的Entry数组,包含的Key为ThreadLocal,值为Object。
原理浅析
ThreadLocalMap
1 | private void set(ThreadLocal<?> key, Object value) { |
ThreadLocalMap的内存泄露问题
我们知道ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal没有外部强引用时,在GC的时候,这个ThreadLocal必然会被回收,但是对应的value不会被回收掉直到线程结束才会被回收。如果当前线程一直处于运行中,那么这些Entry对象中的value就可能一直无法回收,就会发生内存泄露。实际开发中,会使用线程池维护线程的创建和复用,线程为了复用是不会主动结束的,那么ThreadLocal设置的value值就一直被引用,就会发生内存泄露。
如何避免内存泄露
-
线程执行完毕调用remove方法
-
使用ThreadLocal,建议用static修饰 static ThreadLocal
headerLocal = new ThreadLocal(); -
可以在使用ThreadLocal的类上实现AutoCloseable接口,把需要释放的资源(remove)写在close方法里面,把此类写在try后的()里
代码示例:
1 | public class AppContext implements AutoCloseable { |
AutoCloseable是什么
此接口是在jdk1.7之后引入的,可实现自动关闭资源。
值得注意的是,在使用AutoCloseable的时候,必须配合try使用才能自动释放资源,因为利用try(AppContext appContext = AppContext(user)))才能自动调用close()方法。
相关文章: 文章1