多线程--ThreadLocal和内存泄漏

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保存
        在这里插入图片描述
上面这个图可以看出来 Thread ThreadLocal ThreadLocalMap的关系

Thread上有个ThreadLocal,ThreadLocal上有个ThreadLocalMap

在这里插入图片描述

  • 获取当前线程
  • 获取当前线程上的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()掉

一图详解内存泄漏

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值