ThreadLocal

ThreadLocal的应用场景

ThreadLocal这个类在多线程并发中主要的使用场景是什么呢,我们都知道多线程并发问题实际就是多个线程对公共资源访问和修改问题,通过我们之前的分析:

  1. 如果我们的公共资源只是一个int或boolean等基本数据类型的变量,而且只是简单的赋值或查询操作,典型的场景就是各种开关和一些标识位操作,那么我们使用volatile保证变量的可见性就可以了

  2. 如果我们的操作是一个对int的累加操作或其他一些基础类型的累加操作,那么我们使用cas实现的atomic类可以实现简单的原子性操作

  3. 如果我们的操作是多个共享资源或更加复杂的原子性操作,那么我们使用synchronized或lock家族类保证操作的原子性

那么ThreadLocal到底补上了多线程并发中哪种场景的操作?ThreadLocal实际就是处理了一个资源虽然是公共资源,但每个线程都自己独有一份且不需要知道这个资源在其他线程中的状态,各个线程自己本地的公共资源就好了。所以这个资源只跟线程本身有关,随着线程的存在而存在,随着线程的消亡而消亡。比较典型的场景就是每个web请求request对象所带的信息(ip,token,请求参数),所以在好多情况下都会用ThreadLocal保存request。

ThreadLocal是怎么做到把资源绑定到相应线程上的

public void set(T value) {
Thread t = Thread.currentThread();
拿到当前线程,然后通过当前线程获取他的成员变量threadLocals,threadLocals实际就是一个map
ThreadLocalMap map = getMap(t);
当线程的threadLocals不是null时,直接把当前ThreadLocal对象作为key,设置的值作为value放入map中
if (map != null)
map.set(this, value);
else
如果threadLocals是null时,直接new ThreadLocalMap给当前线程的threadLocals成员变量
createMap(t, value);
}

总结:

  1. ThreadLocal实际上是通过Thread的成员变量threadLocals来发挥作用,ThreadLocal对象作为key,设置的值作为value放入threadLocals中,所以你如果使用了ThreadLocal那么当前线程就会使用threadLocals变量持有你设置值的threadlocal对象和这个threadLocal设置的值

  2. 当你用threadLocal对象get方法获取值时就会通过threadLocals变量的map获取这个threadLocal设置的值。因为threadLocals变量是thread的成员变量,所以当当前线程执行完销毁后threadLocals变量也就不存在了,随着线程的存在而存在,随着线程的消亡而消亡。而每个线程都有自己的threadLocals,所以通过threadLocal设置的值会互不干扰,相互隔离。

那为什么说threadLocal可能导致内存泄漏呢

当前线程长时间没执行完而此时又发生GC,而线程成员变量threadLocals指向的ThreadLocalMap是一个map,此时的map是一个数组,数组里放的是Entry,继承于WeakReference,key是threadLocal,value是set的值,而key是一个弱引用,在没有其他对象引用的情况下在gc会被回收,而value是强引用,只要线程不消亡就不会被回收,所以就会造成key为null而value不为null的情况,此时我们已经无法拿到这个value,这就造成了内存泄漏(系统没用的对象占用了内存,而gc又无法回收)。所以在使用threadLocal时一定记得使用finnaly调用remove方法

很多情况下我们都会使用线程池来处理请求和一些业务。线程池里面的线程都是重复使用的,如果在上一次处理业务时没有remove,那么这次从theadLocal拿数据时就会拿到上次请求的数据,这就导致了数据混乱

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值