ThreadLocal白话讲解

threadlocal是什么

每个线程所拥有的私有存储空间,线程间不可访问对方的存储空间。

threadlocal怎么用

是一个以 ThreadLocal 对象为键、任意对象为值的存储结构

ThreadLocal 类常用方法,如下:

protected T initialValue():设置初始值,默认为null
public void set(T value):设置一个要保存的值,并会覆盖原来的值
public T get():获得保存的值,如果没有用过set方法,会获取到初始值
public void remove():移除保存的值

threadlocal需要注意

1. 在线程池中使用

线程池中的线程是可以复用的。每个request请求可复用线程,在复用情况下,若往线程中存入值,复用后的线程中也能拿到值。

存在的问题:

你在某个线程中 threadlocal存入了值any,则通过这个any判断不走某逻辑A。多次request请求,这多次都未存入any值,可还是没走某逻辑A。问题出在多次request请求时,其他有复用了之前的线程,之前线程存入了any值。

解决方案:

每次存入值any后,并进行不走逻辑A后,进行清理any值。通过调用remove()方法。

也可看例子:https://www.jianshu.com/p/53f0a5935205

2. 内存泄露问题

request和ThreadLocal的差别

1)存取值方式不同。

     request根据KEY存取值、一个request可以存多个值。

     ThreadLocal只能存一个值,ThreadLocal的get和set方法没有参数KEY。

2)使用地方不一样。

     request使用在表示层、一般在Action和Servlet中使用。

     ThreadLocal在什么地方都可以、一般用在框架基类中比较多、比如存放当前的数据库连接等。

ThreadLocal的设计是‘空间换时间’,synchronized顺序执行是‘时间换取空间’(抛出问题:synchronized与CAS)

threadlocal存储分析:

ThreadLocal与内存泄漏

图片来着:https://zhuanlan.zhihu.com/p/58636499


1.为什么ThreadLocalMap使用弱引用存储ThreadLocal?

假如使用强引用,当ThreadLocal不再使用需要回收时,发现某个线程中ThreadLocalMap存在该ThreadLocal的强引用,无法回收,造成内存泄漏。

因此,使用弱引用可以防止长期存在的线程(通常使用了线程池)导致ThreadLocal无法回收造成内存泄漏。

2.那通常说的ThreadLocal内存泄漏是如何引起的呢?

我们注意到Entry对象中,虽然Key(ThreadLocal)是通过弱引用引入的,但是value即变量值本身是通过强引用引入。

这就导致,假如不作任何处理,由于ThreadLocalMap和线程的生命周期是一致的,当线程资源长期不释放,即使ThreadLocal本身由于弱引用机制已经回收掉了,但value还是驻留在线程的ThreadLocalMap的Entry中。即存在key为null,但value却有值的无效Entry。导致内存泄漏。

但实际上,ThreadLocal内部已经为我们做了一定的防止内存泄漏的工作。

来着:https://segmentfault.com/a/1190000020914820


抛出问题:

1.  threadlocal为什么要定义成static 、final?

定义成 final 就是为了不能改变。ThreadLocal 就像是一个盒子,大家都可以放取东西。但盒子不能换掉,不然放进去的东西一下子就没了。。。

https://bbs.csdn.net/topics/300229985

2. threadlocal为什么设置key为弱引用?

内存泄漏的真正原因是当前线程持有了Map,导致Map和当前线程的生命周期一样。而不是因为弱引用,弱引用的目的是让key的生命周期不跟着当前线程,减小内存泄露的风险。

https://blog.csdn.net/shuangmulin45/article/details/89084879?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

3. 如何避免threadloacal内存溢出?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值