欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ThreadLocal如何回收value,什么时候回收?

程序员文章站 2023-02-15 15:42:43
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被清空掉,否则就会串到下一次使用。