初识ThreadLocal

ThreadLocal

ThreadLocal的原理

  • 每个线程Thread内部有一个类型为**ThreadLocalMap,名为threadLocals的成员变量。该成员变量类似HashMap, 其中 key为我们定义的ThreadLocal变量的this引用,value则为我们set时候的值,**所以说是每个线程的本地变量是存到到线程自己的内存变量threadLocals里面的

    • ThreadLocal.ThreadLocalMap threadLocals = null; //Thread类
      
  • 例如**set()**方法中

​ a. 首先获取当前线程;然后获取该线程的**ThreadLocalMap**成员变量;

​ b. 如果threadLocals为null,说明是第一次调用set方法,则创建当前线程的threadLocals变量

​ c. 如果不为null,则把value放入当前线程的内存变量threadLocals中。 key就是当前ThreadLocal的实例对象引用,value是通过set方法传递的值

image-20200825134517189
  • set()

    • public void set(T value) {
          Thread t = Thread.currentThread();
          ThreadLocalMap map = getMap(t);
          if (map != null)
              //this 是ThreadLocal, 即new出来的tl
              map.set(this, value);
          else
              createMap(t, value);
      }
      

ThreadLocal的内存溢出

  • Thread中有一个map,就是ThreadLocalMap,ThreadLocalMap的key是ThreadLocal,值是我们自己设定的。ThreadLocal是一个弱引用,当为null时,会被当成垃圾回收
  • ThreadLocal是null了,也就是要被垃圾回收器回收了,但是此时我们的ThreadLocalMap生命周期和Thread的一样,它不会回收,这时候就出现了一个现象。那就是ThreadLocalMap的key没了,但是value还在,这就造成了内存泄漏。
  • **解决:**使用完ThreadLocal之后,应该调用remove方法。因为调用remove方法,就会删除对应线程的threadLocals中的本地变量
  • 使用了线程池,可以达到“线程复用”的效果。但是归还线程之前记得清除ThreadLocalMap,要不然再取出该线程的时候,ThreadLocal变量还会存在。这就不仅仅是内存泄露的问题了,整个业务逻辑都可能会出错。

img

ThreadLocal的应用场景

  • 线程间数据隔离
  • 进行事务操作,用于存储线程事务信息。
  • 数据库连接,Session会话管理。
  • 在进行对象跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值