• ThreadLocal 结构


     
    public
    class Thread implements Runnable {
    
    /* ThreadLocal values pertaining to this thread. This map is maintained
         * by the ThreadLocal class. */
        ThreadLocal.ThreadLocalMap threadLocals = null;
    }

      

    public class ThreadLocal<T> {
    public void set(T value) {
            Thread t = Thread.currentThread();
            ThreadLocalMap map = getMap(t);
            if (map != null)
                map.set(this, value);
            else
                createMap(t, value);
        }
    
    ThreadLocalMap getMap(Thread t) {
            return t.threadLocals;
        }
    
    void createMap(Thread t, T firstValue) {
            t.threadLocals = new ThreadLocalMap(this, firstValue);
        }
    }
    

      

      结合上面的图看,ThreadLocal是线程(Thread)的私有变量,所以不同线程之间的threadLocal变量是隔离出来的,只能同一个线程取。Thread下面有一个成员变量threadlocals指向着ThreadLocalMap(可以看成一个hashMap),Entry对象里面的keyvalue分别是ThreadLocal和对应的value值。

      ThreadLocal容易发生内存泄漏,当线程没有销毁,一直存在的时候,随着时间的延长,ThreadLocal里面的Entry会越来越多。(根可达性算法GC,线程(Thread)下的属性变量threadLocls无法被回收)

      原来 ThreadLocal 的 ThreadLocalMap 里面存的每一个 Entry 是一个 WeakReferenceWeakReference 会在 GC 的时候进行回收,回收的其实是 key,也就是弱引用的 referent, 然后  ThreadLocal 会在 set 和 get 的时候对 key 为空的 value 进行删除,所以这样就完美解决了当前线程生命周期不结束的时候,不同的 ThreadLocal 不停的追加到当前线程上面,导致内存溢出。

      所以使用完毕不用后应该调用ThreadLocal.remove() 移除entry,防止应为value的强引用导致无法被gc回收。

    使用方法
    
     pulic static ThreadLocal<String> str = new ThreadLocal<>();
    
    
    str.set("aaa");
    
    str.get("aaa");
    
    str.remove();
    

      

  • 相关阅读:
    使用js方法时,调用的方法名明明一致,但就是不管用,解决
    最近ssh遇到异常及解决
    oracle中number数据类型简单明了解释
    Struts2 使用Jquery+ajax 文件上传
    PHP学习记录(二)
    PHP学习记录(一)
    Win7下Git SSH 创建Key
    webapck基础随手记
    分享一份JS前端面试题
    Redux零碎知识点回顾
  • 原文地址:https://www.cnblogs.com/chenfx/p/14380095.html
Copyright © 2020-2023  润新知