口试官:ThreadLocal利用场景有哪些?内存泄漏问题怎样克制?

开发者 2024-9-11 05:07:19 2 0 来自 中国
ThreadLocal利用场景有哪些?

1.png 保举学习:必刷的30万口试题:巧用弱引用办理ThreadLocal内存走漏!

Thread类中有两个变量threadLocals和inheritableThreadLocals,二者都是ThreadLocal内部类ThreadLocalMap范例的变量,我们通过查看内部内ThreadLocalMap可以发现现实上它类似于一个HashMap。在默认情况下,每个线程中的这两个变量都为null:
ThreadLocal.ThreadLocalMap threadLocals = null;ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;只有当线程第一次调用ThreadLocal的set大概get方法的时间才会创建他们。
public T get() {        Thread t = Thread.currentThread();        ThreadLocalMap map = getMap(t);        if (map != null) {            ThreadLocalMap.Entry e = map.getEntry(this);            if (e != null) {                @SuppressWarnings("unchecked")                T result = (T)e.value;                return result;            }        }        return setInitialValue();}ThreadLocalMap getMap(Thread t) {        return t.threadLocals;}除此之外,每个线程的本地变量不是存放在ThreadLocal实例中,而是放在调用线程的ThreadLocals变量内里。也就是说,ThreadLocal范例的本地变量是存放在具体的线程空间上,其自己相当于一个装载本地变量的载体,通过set方法将value添加到调用线程的threadLocals中,当调用线程调用get方法时间可以大概从它的threadLocals中取出变量。如果调用线程不绝不停止,那么这个本地变量将会不绝存放在他的threadLocals中,以是不利用本地变量的时间必要调用remove方法将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);}public void remove() {         ThreadLocalMap m = getMap(Thread.currentThread());         if (m != null)             m.remove(this);}ThreadLocal内存泄漏问题怎样克制?

每个Thread都有一个ThreadLocal.ThreadLocalMap的map,该map的key为ThreadLocal实例,它为一个弱引用,我们知道弱引用有利于GC接纳。当ThreadLocal的key == null时,GC就会接纳这部门空间,但是value却不愿定可以大概被接纳,由于他还与Current Thread存在一个强引用关系,如下
由于存在这个强引用关系,会导致value无法接纳。如果这个线程对象不会烧毁那么这个强引用关系则会不绝存在,就会出现内存走漏情况。以是说只要这个线程对象可以大概及时被GC接纳,就不会出现内存走漏。如果碰到线程池,那就更坑了。 那么要怎么克制这个问题呢? 在前面提过,在ThreadLocalMap中的setEntry()、getEntry(),如果碰到key == null的情况,会对value设置为null。固然我们也可以表现调用ThreadLocal的remove()方法举行处理惩罚。 下面再对ThreadLocal举行简单的总结:

  • ThreadLocal 不是用于办理共享变量的问题的,也不是为了调和线程同步而存在,而是为了方便每个线程处理惩罚自己的状态而引入的一个机制。这点至关紧张。
  • 每个Thread内部都有一个ThreadLocal.ThreadLocalMap范例的成员变量,该成员变量用来存储现实的ThreadLocal变量副本。
  • ThreadLocal并不是为线程生存对象的副本,它仅仅只起到一个索引的作用。它主要是为每一个线程隔离一个类的实例,这个实例的作用范围仅限于线程内部。
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-18 20:32, Processed in 0.181687 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表