• 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();
    

      

  • 相关阅读:
    经典回溯问题- 迷宫
    关于二叉树的一点补充。
    二叉树重难点总结(判断完全二叉树,非递归前、中、后序遍历的实现等...)
    栈、队列常规操作
    贪吃蛇小游戏
    链表重点问题(下)
    链表常见问题(上)
    动态顺序表
    时间 空间复杂度小结(斐波那契 二分查找举例)
    每天一个linux命令-id,输出用户的uid、gid
  • 原文地址:https://www.cnblogs.com/chenfx/p/14380095.html
Copyright © 2020-2023  润新知