当前位置:网站首页>面试官:ThreadLocal使用场景有哪些?内存泄露问题如何避免?
面试官:ThreadLocal使用场景有哪些?内存泄露问题如何避免?
2022-07-28 17:06:00 【nuzzzzz】
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并不是为线程保存对象的副本,它仅仅只起到一个索引的作用。它主要是为每一个线程隔离一个类的实例,这个实例的作用范围仅限于线程内部。
边栏推荐
- Wired: who owns the art of the future? Openai allows dall-e users to commercialize their works. At present
- 2022.7.26 构造函数,面试:new的作用、深拷贝和浅拷贝
- Docker builds MySQL master-slave replication
- Noise of creative coding
- What is the employment prospect of software testing?
- Ue5 gas learning notes 1.5 gameplay effects game effects
- Error 2003 (HY000) can't connect to MySQL server on 'localhost3306' (10061) solution
- Look at Devops construction from SRE
- 腾讯汤道生:开源是产业互联网时代新的生产方式和协作模式
- 1.3、链表
猜你喜欢

2022-07-27 第四小组 修身课 学习笔记(every day)
![[GXYCTF2019]StrongestMind](/img/f4/61932548e0c7dd60d790d31fb5b96b.png)
[GXYCTF2019]StrongestMind

Introduction and advanced level of MySQL (8)

专题讲座6 树形dp 学习心得(长期更新)

1.1、稀疏数组

Detailed explanation of network RJ45 interface

Noise of creative coding

MySQL advanced mvcc (ultra detailed collation)

实验楼----PHP大法

Calibration of vector network analyzer (vector network)
随机推荐
GC垃圾回收器详解
Ue5 gas learning notes 1.4 attribute set
Detailed explanation of network RJ45 interface
Ue5 gas learning notes 1.10 prediction
MYSQL入门与进阶(四)
MYSQL入门与进阶(六)
jvm四种引用类型
明德生物:公司暂未有产品被列入WHO推荐清单
@Autowired与@Resource区别
欧美六国最快5日达 菜鸟推出快线产品 优化“端到端”履约服务
Six countries in Europe and the United States launched an express line product to optimize the "end-to-end" performance service on the 5th
The required error of solidity is reported
一文简述:SRv6基本原理
Gaode map realizes customized small blue dots, customized point markers, drawing polygon / circular areas, and displaying or hiding customized point markers according to the movement of the map
.net WCF WF4.5 状态机、书签与持久化
MYSQL入门与进阶(七)
Ue5 gas learning notes 1.8 game special effects (gameplaycue)
UE5 GAS 学习笔记 1.10 预测(Prediction)
MYSQL入门与进阶(三)
Docker builds MySQL master-slave replication