美文网首页
ThreadLocal

ThreadLocal

作者: 囧囧有神2号 | 来源:发表于2018-05-06 23:46 被阅读0次

    什么是ThreadLocal?它是属于线程自己的小仓库。也就是在堆中创建一个线程自己才能访问到的对象,利用线程封闭来确保安全。

    图片来自占小狼

    使用时会创建一个ThreadLocal静态变量,然后在方法中调用set,第一次调用set时会创建一个ThreadLocalMap对象,将其赋给线程的ThreadLocal.ThreadLocalMap threadLocals

        public void set(T value) {
            Thread t = Thread.currentThread();
            ThreadLocalMap map = getMap(t);
            if (map != null)
                map.set(this, value);
            else
                createMap(t, value);
        }
    
        void createMap(Thread t, T firstValue) {
            t.threadLocals = new ThreadLocalMap(this, firstValue);
        }
    //-----------------------------------------------------
        ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
            table = new Entry[INITIAL_CAPACITY];
            int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
            table[i] = new Entry(firstKey, firstValue);
            size = 1;
            setThreshold(INITIAL_CAPACITY);
        }
    

    ThreadLocalMap是ThreadLocal的静态内部类,ThreadLocalMap里有一个Entry的静态内部类。这三者啥关系?存储key,value的是Entry,ThreadLocalMap封装Entry实现主要功能,ThreadLocal对ThreadLocalMap进一步封装,使得调用非常简便;
    现在想想上面说的当你第一次调用set后,堆中是什么情况?

    • 堆中一个ThreadLocal实例,它是静态的所以只会存在一个,多个线程共享它。
    • 每个线程都会有一个自己的ThreadLocalMap实例,分析一下它们的可达性,只有本线程的threadLocals变量指向它,也就是说当线程执行完毕,线程的ThreadLocalMap实例会被GC清除。
    • 每个线程还会在堆中创建只有自己可达的Entry数组对象,ThreadLocalMap里的table指向它,它的key是ThreadLocal实例,所以当线程销毁,Entry仍有可达性,ThreadLocal是静态的那Entry就永远不会被销毁了,OOM!所以引入了弱引用WeakReference,将Entry里对ThreadLocal引用设为弱引用,当只有弱可达性时,Entry会被清理;

    如上面所说的,那么要是Thread一直不销毁呢?仍然会发生OOM!
    如何防止?ThreadLocal在set,get方法调用时都会主动清理Entry[]中key为null的entry;在使用时一个良好的习惯便是主动清理,

    try{
      //do
    }finally{
      threadLocal.remove();
    }
    

    这样便能避免OOM;

    我们从线程安全方面想想,为什么不直接在方法中创建一个仓库实例,它也是利用线程封闭,安全,不就不用这么麻烦了吗?那么当你想在其它地方获取存储值时只能将它传递过去,这就相当于你将这个实例发布出去了,这就存在安全隐患,而且传递来传递去非常不方便;我们再来看看ThreadLocal的设计,如前面分析的一样,它非常巧妙,让人感叹啊!

    其他方面比如ThreadLocal利用hash来定位,用线性探测法来解决hash冲突。

    相关文章

      网友评论

          本文标题:ThreadLocal

          本文链接:https://www.haomeiwen.com/subject/utyprftx.html