ThreadLocal使用及原理

本文详细介绍了ThreadLocal的作用,如何在多线程环境中存储和获取线程专属变量,涉及ThreadLocal的工作原理、数据结构以及为何选择线性探测法。通过实例演示了ThreadLocal如何解决线程间数据隔离问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.简介及作用

    在一些场景中,我们希望一些变量只能被某个线程访问,对其他线程是隔离的,就需要用到ThreadLocal.

    ThreadLocal具有线程隔离性,用于解决多线程中相同变量的访问冲突问题.使每个线程读到的变量都是相独立的.线程内部变量仅相对于本线程而言可见.

二.简单使用

存储值,直接调用set()方法
取值,直接调用get()方法.

 ThreadLocal<String> threadLocal = new ThreadLocal<>();

        for (int i = 0; i < 5; i++) {
            String threadName = "Thread" + i;
            new Thread(() -> {
                threadLocal.set(threadName);
                System.out.println(threadName + "获取到值:" + threadLocal.get());
                threadLocal.remove();
            }, threadName).start();
        }

输出结果:
在这里插入图片描述

注意:针对同一个Thread,ThreadLocal 只能存储一个值,如下案例:
在这里插入图片描述

三.原理:

  1. 首先Thread有一个成员变量ThreadLocal.ThreadLocalMap,也就是每一个Thread都自身绑定了一个ThreadLocal.ThreadLocalMap.
    在这里插入图片描述

  2. 而ThreadLocal的静态内部类ThreadLocalMap,最主要的结构就是一个entry数组.
    在这里插入图片描述

  3. 在存储元素的时候,首先我们能根据当前thread获取到当前绑定的ThreadLocalMap,然后利用threadlocalMap中的threadLocalHashcode()方法计算出当前要存储的entry数组中的下标位置,key就是threadLocal对象,value就是要存的值,组成一个entry存进去.
    在这里插入图片描述

  4. 取元素的时候也是根据当前线程对象,拿到threadLocalMap,再根据this(threadLocal对象)计算hash值,找到下标,取值即可

四.自问自答

  1. 存储的数据结构是什么样的
    thread.ThreadLocal.ThreadLocalMap–>[<threadLocal1,value1>,<threadLocal2,value2>]

    数组中的下标就是通过当前threadLocal对象hash得到的.

  2. 为什么要传一个数组呢?
    对每一个线程来说,可能要存储的与之相关联的变量不只一个,所以必然需要一个集合去存储这些值.

  3. 当发生Hash冲突的时候是怎样处理的?
    ThreadLocal里面就有一个数组,不像hashMap,是数组+链表的结构,那么当ThreadLocal发生hash冲突的时候就会用到线性探测法,简单来说就是当冲突的时候,依次查找列表中离冲突单元最近的空闲单元,并且把新的键插入这个空闲单元.

  4. 为什么要用线性探测法?
        ThreadLocal 往往存放的数据量不会特别大(而且key 是弱引用又会被垃圾回收,及时让数据量更小),这个时候开放地址法简单的结构会显得更省空间,同时数组的查询效率也是非常高,加上第一点的保障,冲突概率也低

    开方地址法的缺点是容易产生堆积,不适用于大规模的存储.
    链地址法:不存在堆积问题,冲突处理简单,适合大数据存储.

  5. 为什么要是一个entry数组呢,不是一个单泛型得数组,比如说String数组?
        其实终其原因,是因为其在hash冲突的时候使用了线性探测法,会依次往后寻找空位置去插入,
    那么当我们去取值的时候,发生hash冲突,就得往后依次遍历比较哪一个是和我们存进去得key相等,才进行返回

今天的分享就到这里了,有问题可以在评论区留言,均会及时回复呀.
我是bling,未来不会太差,只要我们不要太懒就行, 咱们下期见.
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员bling

义父,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值