多线程--ThreadLocal和内存泄漏
程序员文章站
2022-03-08 22:37:40
...
ThreadLocal
- threadlocal是一个线程内部的存储类,可以在指定线程内存储数据,数据存储以后,只有指定线程可以得到存储数据
public class Thread_19_Thread_Local {
public static class Person{
Person(String userName){
this.userName=userName;
}
String userName;
public String getUserName(){
return userName;
}
}
public static void main(String[] args) {
ThreadLocal<Person> threadLocal = new ThreadLocal<Person>();
new Thread(()->{
try{
Thread.sleep(2000);
Person person = threadLocal.get();
System.out.println("线程二:"+person);
}catch (Exception e){
}
}).start();
new Thread(()->{
try{
Person p = new Person("lhy");
threadLocal.set(p);
Person person = threadLocal.get();
System.out.println("线程一:"+person);
}catch (Exception e){
}
}).start();
}
}
为什么会这样呢?来see see 源码
- 获取当前线程
- 获取当前线程上的Thread.ThreadLocal.ThreadLocalMap
- 如果map != null
- map.set(this,value)
- key threadLocal
- value 入参保存值
- createMap(t,value)
- 创建一个map保存
- 创建一个map保存
- map.set(this,value)
- 获取当前线程
- 获取当前线程上的Thread.ThreadLocal.ThreadLocalMap
- 如果map != null
- 以ThreadLocal为key 拿取对应的value
- 返回一个null
内存泄漏
代码举例:
ThreadLocal<M> tl = new ThreadLocal<>();
new Thread(()->{
tl.set(new Person("lhy"));
tl.remove();
}).start();
- 当方法执行的时候,线程中的 tl 跟方法中的new ThreadLocal() 有引用 引用1
- 每个线程中有自己的Thread.ThreadLocal.ThreadLocalMap
- map中key 为 new ThreadLocal() 引用3
- value 为入参值
- 如果为引用3 为强引用的话
- 当方法结束,引用1 断开
- 但是线程还存在,所有引用3还存在,导致new ThreadLocal()空间还存在
- 导致内存泄漏
如果为弱引用的话
- 当方法结束,引用1 断开
- 由于引用3为弱引用,垃圾回收的时候,就会被回收走
- 所有 new ThreadLocal() 空间没有引用连接,会被回收
那还存在内存泄漏问题吗?
- 答案是存在的
- 虽然方法结束了,引用1 引用3 断开了
- 但线程存在,ThreadLocal存在,ThreadLocalMap也存在
- ThreadLocalMap 中的key 为空值, 但value 还指向一块内存地址,没有被回收
- 所以还存在内存泄漏问题
解决方案
- 当ThreadLocal使用完成时
- remove()掉
上一篇: 多线程学习:如何改变线程执行顺序