ThreadLocal中为什么使用弱引用
补个概念:
ThreadLocalMap中的key就是Entry,Entry是一个弱引用,关联了当前ThreadLocal对象。需要存储的数据为值。调用set方法要传入两个参数ThreadLocal对象和要存入ThreadLocal对象的数据。
如下图:threadLocal.set(new User(1,"main线程对象")); 这行代码(User类是一个自定义类,threadLocal是当前线程)。等于说通过Entry弱引用,既可以找到ThreadLocal对象,又可以找到存放的value值
同理:get方法可以获取数据
为什么ThreadLocal要使用弱引用?
现在我们调用 threadlocal = null; 使静态变量和ThreadLocal对象之间的强引用关系去掉。现在这个ThreadLocal对象就可以被回收。根据弱引用的特点:假设某个对象只有弱引用关联,该对象是可以被回收的!(假设Entry和ThreadLocal之间使用强引用,没人指向这个ThreadLocal对象,但它还是不能被回收,就出现内存泄漏!)
总结一下使用弱引用的好处:如果ThreadLocal对象不再使用了(不再被引用了)。尽管它还被ThreadLocalMap引用着,它依然可以被回收。
还有一个问题:由于Entry和value之间是强引用,那么这个value对象如何被回收呢?
由于之前ThreadLocal对象已经没有强引用了,它就会被回收。现在调用set/get/remove方法时,发现当前Entry所关联的ThreadLocal已经没有了。这个Entry所关联的value对象也会被回收。
但如果一直没有调用set、get、remove方法,那么这个Entry和value就一直不会被回收,从而可能导致内存泄漏。如何解决呢?
因此,当我们某个ThreadLocal不再使用了,就要手动调用remove方法将ThreadLocalMap和Entry之间的引用断掉。这样垃圾GC Root找不到这两个对象,就会被垃圾回收了!
总结