Java的ThreadLocal实现线程隔离的原理

1. ThreadLocal 和 ThreadLocalMap,Thread的关系

在这里插入图片描述
在这里插入图片描述

  1. Thread里面有一个ThreadLocalMap的对象,注意这是每一个线程独有的
  2. ThreadLocalMap存的一个Entry,可以简单理解为键值对,键为ThreadLocal对象,值为Object(即我们存的值)

2. 如何实现

  • 我们先来看看线程操纵资源类的例子代码
class threadTest{
    //将 tl初始化为0
    ThreadLocal<Integer> tl = ThreadLocal.withInitial(()->0);
    int get(){
       return  tl.get();
    }
    void put(int val){
         tl.set(tl.get()+val);
    }

}
public class test22 {
    public static void main(String[] args) {
        threadTest threadTest = new threadTest();
        for(int i=1;i<=5;i++){
            int val = i;
            new Thread(()->{
                threadTest.put(val);
                System.out.println(threadTest.get());
            }).start();
        }
    }
}
  • 每一个线程都分别执行一个put操作,设置的值就是for循环的i的值,那我们看看结果是什么
1
3
2
4
5
进程已结束,退出代码为 0
  • 可以看到每一个线程操作同一个资源类的同一个ThreadLocal对象,我们发现每一个线程都是操作自己的ThreadLocal。那我们来看看ThreadLocal的set操作究竟如何实现这样的功能(get操作同理)
  • 这是threadlocal的set操作
    在这里插入图片描述
  • 我们在看看 set(Thread.currentThread(), value);是怎么写的,记住这里传的参数Thread.currentThread()是指当前的线程,这是一个静态的方法,返回的就是当前线程对象!这一点很关键,有了这一个Thread.currentThread()我们可以去操作每一个线程的threadlocalmap对象了!
    在这里插入图片描述
    这里的set方法传入了当前的线程对象,然后拿到一个threadlocalmap对象
    然后对这个map对象进行set操作,这就像普通的键值对赋值了,关键是我们获取的threadlocalmap究竟是什么!点进去看看源码
    在这里插入图片描述
    到这个我觉得已经真相大白了。这里传的线程t是当前线程,t.threadlcals就是当前线程的threadlocalmap
    在这里插入图片描述
    因此当线程操作同一个资源类的threadlocal对象的时候,像在这个set的过程可以分为如下几步:
    1. 首先调用set方法传入的参数是要设置的value,还有一个是当前的线程对象Thread.currentThread()
    2. 然后根据当前的线程对象获取到每一个Thread里面的ThreadlocalMap
    3. 然后对这个threadlocalmap进行设置key-value,key是同一个资源类的threadlocal对象,value就是传入的值
    4. 注意我们操作的始终是同一个对象,因此threadlocalmap设置的key始终是同一个threadlocal对象
    5. 这样我们就可以实现不同的thread,通过同一个threadlocal设置不同的value
其实threadlocal的get操作也是一样的
  • 根据Thread.currentThread()找到当前的线程对象
  • 然后找到当前线程thread的threadlocalmap,根据同一个资源类的同一个threadlocal对象(键)获取不同的value(值)

可以通过下面的图来理解

在这里插入图片描述

分析就到这里,欢迎大家提出问题,共同进步

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值