ThreadLocal-全概念解析

介绍

ThreadLocal 提供线程局部变量,ThreadLocal实例通常是线程私有静态字段,使用的目的是希望将线程与状态关联起来。与JMM中局部变量有几分相似之处,但是不用写回主内存(如果违反,那就线程不安全),Thread用完要remove(),特别在线程池的情况下,会出现内存泄漏。

Thread、ThreadLocal、ThreadLocalMap


ThreadLocal.ThreadLocalMap 各自线程拥有自己的Map。

  • 注意😒😒😒
    思考:为什么要在线程中使用ThreadLocalMap?为什么是Entry数组
    因为一个线程可以拥有多个ThreadLocal,没错,多个ThreadLocal变量。

强、软、弱、虚


强引用:普通对象引用。

Student a=new Student();
a=null;

软引用:内存足够时保留,内存不够时会回收
弱引用:只要gc就回收
虚引用:在对象回收后进行通知,放入引用队列。

什么是内存泄漏?

不再会被使用的对象,不能被回收。

为什么会出现内存泄漏?

key是弱引用,被回收后,value没有被回收。

threadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal不存在外部强引用时,Key(ThreadLocal)势必会被GC回收,这样就会导致ThreadLocalMap中key为null, 而value还存在着强引用,只有thead线程退出以后,value的强引用链条才会断掉。
但如果当前线程再迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:

Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value

永远无法回收,造成内存泄漏。

仔细想想,ThreadLocal 下面这个设计值得学习

  1. Thead 线程中有ThreadLocalMap
  2. 在线程内创建ThreadLocal会自动放进ThreadLocalMap
        ThreadLocal<String> threadLocal = new ThreadLocal<>();
        threadLocal.set("123");
    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = t.threadLocals;
        if (map != null) {
            map.set(this, value);
        } else {
            createMap(t, value);
        }
    }

更新一下,我想给你讲明白ThreadLocal

现在时间2023-07-05-00:37
提前声明,如有理解错误,本人概不负责。😁


面试官:你好同学,简单一个面试题,八股文,来,对象会创建在什么区域?
小涛:堆(简洁明了,不拖泥带水,声音洪亮)
面试官:offer给你了,拿去。😊


面试官:那么假如线程执行过程中发生GC,内存不够了嘛,key不是弱引用嘛,发生GC就会销毁,ThreadLocalMap key会不会被销毁,再说明一下问题也就是说key指向的ThreadLocal会不会被回收?
小涛:如回 如来到底来没来 如来
面试官:offer给你了,拿去。😊,到底回没回收?

首先搞清楚,ThreadLocal 在线程执行过程中,会不会回收?你觉着应不应该被回收,那当然不能被回收,线程中创建的对象放在堆区,线程中局部变量表指向堆区对象,线程执行过程中,指针一直会指向堆区对象(强引用),那么堆中的对象怎么会被回收呢?

那什么时候这些强引用会被销毁呢?线程结束,栈帧弹出,引用是不是没了?假如果ThreadLocalMap 中key是强引用,也就如下图:

那你说说ThreadLocal 对象会不会被回收?那不是有key的强引用嘛。只要ThreadLocalMap不回收,ThreadLocal对象就不会被回收。

设计师设计成弱引用,gc时候发现ThreadLocal对象只有弱引用,那么会直接将对象回收,剩下的ThreadLocalMap话,交给系统进行回收嘛。

面试官:说了这么多,那你说说,现在ThreadLocal为什么会存在内存泄漏的风险?
:ThreadLocalMap交给系统回收?什么时候回收?value中的对象什么时候释放?ThreadLocalMap不回收,value不会释放。所以我们要养成手动remove的好习惯,当然ThreadLocal里面也做了优化,比如某些时候看到Key被回收时,会释放value。

posted @ 2023-06-08 23:32  帅气的涛啊  阅读(9)  评论(0编辑  收藏  举报