(jdk1.8)
ThreadLocal类似于线程局部变量,但是如果操作不当会引起内存泄漏,解决办法是手动调用remove()方法移除k-v对,还有一种方法是调用set方法,会自动检查键为null的kv对。
为什么会内存泄漏:
ThreadLocal内部维护了一个ThreadLocalMap:


key是弱引用(WeakReference),value是强引用,k/v对封装在Entry节点中。
public testThreadLocal(){
ThreadLocal threadLocal=new threadLocal();
threadLocal=null; //GC
}
这段代码,threadLocal占用的对象内存将会被回收,它内部的ThreadLocalMap中的key是弱引用,只要内存不足就会将它回收,但是value是强引用,很难被回收。假设现在key已经被回收了,key==null,key对应的value永远无法访问到,因此会内存泄漏。
Q:那为什么不把value也设置成弱引用呢?
A:假设value也是弱引用,现在内存不足了,value被回收,即value==null,这时调用threadLocal.get(key)返回的是null,将会返回错误的结果,因此value是强引用。
Q:那为什么不把key设置成强引用呢?
A:假设key是强引用,虽然testThreadLocal()方法中threadLocal以经设置成null了,但是ThreadLocalMap中还保持着对key的强引用,key引用指向的内存照样无法回收,因此key不能设置成强引用
如何解决内存泄漏:
1:手动使用remove()方法去除kv对

2:ThreadLocal本身也做了优化,调用set()方法会自动检测key为null的value,然后去除value
部分代码如下:

但是,并不是每次调用set()都会检查到,第一个
if(k==key){
e.value=value;
return;
}
如果在循环第一次就成立,直接return了,跳出方法,后面的就不执行了。