ThreadLocal知识点小记录

场景

调用第三方的接口,有很多个,每个接口参数都要传token或者用户id,每个方法都要定义参数,显然过于繁琐,所以想到用ThreadLocal来实现,但是发现知识点忘了很多,所以看看别人的文章整理下,以后随时补充新的知识点。

用法

在这里插入图片描述
声明一个变量,然后在某个地方进行set相关值后,在某个地方进行获取

它是如何保证每个线程相互不影响值呢

set值的时候,是从当前线程对象中获取threadLocals属性,类似map,然后往里放value ,key就是this即我们new出来的那个ThreadLocal对象,所以threadlocalMap是属于各自线程的成员属性,所以不影响,同时也不需要用锁之类
在这里插入图片描述
在这里插入图片描述

声明threadLocal变量为静态成员变量原因

从源码中可以看出,threadlocalMap是在各自的线程里面的维护的,所以不存在冲突和竞争关系,那么threadLocal变量就没必要声明为局部变量,造成空间的浪费了,所以往往声明为静态变量,提高内存利用率

ThreadLocalMap的key是弱引用的目的

在这里插入图片描述
从源码中可以看出threadLocalMap的key是弱引用,弱引用???啥是弱引用,弱引用是啥??
度娘了解一番:

  • 当你new出来的对象,在没有任何强引用连接它的时候,没有任何强悍的东西,而且此时只有弱引用,那么这个对象在下一次GC来临之前就会被回收掉,如果这个对象此时连弱引用都么有,那么它肯定也会被回收掉。**所以弱引用是一个不足以强迫对象保留在内存中的引用,不影响垃圾收集器回收对象**
  • 软引用呢,它比弱引用强悍一点,它引用的对象,如果内存充足,就一直存在,如果内存吃紧,那么就会回收它;会尽可能长的保留引用直到 JVM 内存不足时才会被回收,仅此而已的区别
  • 重点来了:所以当threadLocal对象没有强引用指向他的时候即threadLocal=null这样;那么threadLocalMap中的key就只剩下弱引用了,那么下次GC来的时候,就会回收掉threadLocal实例对象;
             key就变成了null;**所以弱引用的使用目的就是为了回收掉threadLocalMap中的key,这样当线程结束的时候,就全部都释放了,value也没人引用了**,,但是我们常规开发下,threadLocal对象一般都是static修饰,意味着它的生命周期就延长很多了,所以此时弱引用其实意义没那么大了
  • 重点的重点:如果此时线程使用的是线程池,那么即使你的threadLocal实例对象不是静态变量方式声明,作为局部变量声明,threadLocal对象为null的时候,但是线程却没有结束生命周期,那么threadLocalMap中的Entry对象就一直引用着那个value对象,导致这个value没有被回收掉,因为线程没结束啊,那就一直引用Entry对象,所以Entry里面的value就一直被引用无法回收,这种情况,线程一旦多起来,就内存泄露报错了,这个可能就是传说中内存泄露的情况,所以要想个办法,当key为null的时候,将value也变成null,这样就能回收对象了;
  • 所以在使用threadLocal变量set之后,记得在finally下进行threadLocal.remove下,还有在全局异常处理的时候也记得remove
  • 贴张图,加深下上面的理解
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    这篇博客写着也不错,点
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值