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

2019-08-09 00:00:00 回收 什么时候 ThreadLocal

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被清空掉,否则就会串到下一次使用。

相关文章