ThreadLocal如何回收value,什么时候回收?
程序员文章站
2023-12-24 16:05:21
1)ThreadLocal如何回收value,什么时候回收?从ThreadLocal中的内部类分析:① ThreadLocalMap是一个定制的哈希映射,仅适用于维护线程本地值。为了帮助处理非常大和长期使用的用法,哈希表条目使用weakreferences作为键。但是,由于不使用引用队列,因此只有当 ......
1)threadlocal如何回收value,什么时候回收?
从threadlocal中的内部类分析:
①
static class threadlocalmap { /** * the entries in this hash map extend weakreference, using * its main ref field as the key (which is always a * threadlocal object). note that null keys (i.e. entry.get() * == null) mean that the key is no longer referenced, so the * entry can be expunged from table. such entries are referred to * as "stale entries" in the code that follows. */ ...... }
threadlocalmap是一个定制的哈希映射,仅适用于维护线程本地值。为了帮助处理非常大和长期使用的用法,哈希表条目使用weakreferences作为键。但是,由于不使用引用队列,因此只有当表开始耗尽空间时,才保证删除过时的条目。(源码注释)
②
static class entry extends weakreference<threadlocal<?>> { /** the value associated with this threadlocal. */ object value; entry(threadlocal<?> k, object v) { super(k); value = v; } }
threadlocalmap是使用threadlocal的弱引用作为key的(注意:value并非弱引用),key只能是threadlocal对象,从而实现了变量访问在不同线程中的隔离。当一个threadlocal失去强引用,生命周期只能存活到下次gc前,此时threadlocalmap中就会出现key为null的entry,当前线程无法结束,这些key为null的entry的value就会一直存在一条强引用链,造成内存泄露。
解决方案:
建议将threadlocal变量定义成private static的,在调用threadlocal的get()、set()方法完成后,再调用remove()方法,手动删除不再需要的threadlocal。
2)threadlocal为什么会产生脏数据?
因为thread pool是一把双刃剑,好处略,坏处之一:
如果thread是从thread pool中取出,它可能会被复用,此时就一定要保证这个thread在上一次结束的时候,其关联的threadlocal被清空掉,否则就会串到下一次使用。