ThreadLocal原理

(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了,跳出方法,后面的就不执行了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容