ThreadLocal
ThreadLocal是JDK包提供的,它提供线程本地变量,为当前线程提供了一个存储变量的副本,当我们在多线程场景下,想要让每个线程都拥有自己独立的”线程上下文变量“,就可以使用ThreadLocal来存储一个仅限当前线程内部使用的共享对象
静态内部类ThreadLocalMap
定义在ThreadLocal类中,在Thread类中被使用到
类似一个HashMap,泛型为<ThreadLocal,Object>,用来存储当前线程的ThreadLocal变量
threadLocals属性(Thread类拥有)
ThreadLocal.ThreadLocalMap threadLocals = null;
引用ThreadLocalMap类的注释:该类是包私有的,以允许在类 Thread 中声明字段。为了帮助处理非常大且长期存在的实例,哈希表条目使用 WeakReferences 作为键。但是,由于不使用引用队列,因此只有在表开始空间不足时才能保证删除过时的条目。
ThreadLocalMap静态内部类Entry
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
ThreadLocalMap 中使用的 key 为 ThreadLocal 的弱引用,而 value 是强引用
因此,ThreadLocalMap在没有外部强引用的情况下,在GC发生时,Entry中的Key因为弱引用会变为null,Object(value)则不会被清理掉,这样一来ThreadLocalMap中就会出现key为null的Entry
ThreadLocal内存泄漏分析与解决方案
假如我们不做任何措施的话,value 永远无法被GC 回收,这个时候就可能会产生内存泄露
ThreadLocalMap实现中已经考虑了这种情况,在调用 set()、get()、remove() 方法的时候,会清理掉 key 为 null 的记录。使用完 ThreadLocal方法后 最好手动调用remove()方法
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1300452403@qq.com