让人迷糊的ThreadLocalMap,看清他的本质

本文解析了ThreadLocalMap的数据结构,它本质上是一个Array,存储与当前线程绑定的数据。ThreadLocalMap的工作原理涉及ThreadLocal对象的nextHashCode方法,确保线程安全。ThreadLocal可视为线程的私有空间,调用方法时在各自线程的ThreadLocalMap中操作。
摘要由CSDN通过智能技术生成
ThreadLocalMap

ThreadLocalMap是ThreadLocal的内部类,主要提供了数据存储和获取的API和存储真实数据的数据结构

我们怎么才能更好的理解这个数据机构呢,首先给出答案:其实我们被他的名字弄迷糊了,他存数据的结构其实本质上是一个Array,我们把ThreadLocalMap改名成ThreadLocalArray就很清晰了;

我们调用ThreadLocal的set方法保存数据时,会经历以下流程:
1、获得当前的线程对象
2、获得当前线程对象的ThreadLocalMap属性
3、如果ThreadLocalMap属性不为空,则调用ThreadLocalMap类的set方法
4、如果ThreadLocalMap属性为空,则通过ThreadLocalMap的构造方法创建一个ThreadLocalMap对象

ThreadLocalMap底层的数据结构是一个数组,看一下如下图就很清晰了:

在这里插入图片描述

Entry

首先给出答案吧,一个Entry对应的是一个 new ThreadLocal()对象执行set方法后保存的值;
比如我们项目中创建了多个ThreadLocal对象A、B、C并且每一个对象都调用了set方法,那么上面的数组就会被填充多个值;

Entry定位规则

底层原理就是根据上面的对象A、B、C计算出这些对象在Entry数组中应该占用的位置,然后将set方法传的值保存进去
定位规则是调用ThreadLocal对象A、B、C的 nextHashCode()方法然后和Entry数组的容量做余数

Entry数组是Object数组,所以可以存任何类型

nextHashCode方法
    private final int threadLocalHashCode = nextHashCode();

    /**
     * The next hash code to be given out. Updated atomically. Starts at
     * zero.
     */
    private static AtomicInteger nextHashCode =  new AtomicInteger();

    /**
     * The difference between successively generated hash codes - turns
     * implicit sequential thread-local IDs into near-optimally spread
     * multiplicative hash values for power-of-two-sized tables.
     */
    private static final int HASH_INCREMENT = 0x61c88647;

    /**
     * Returns the next hash code.
     */
    private static int nextHashCode() {
        return nextHashCode.getAndAdd(HASH_INCREMENT);
    }

重点:
1、上图这一系列的数据都与当前线程绑定的,即不同线程操作ThreadLocal方法都是操作自己线程的数据,不会有线程安全问题
2、ThreadLocal可以理解成一个门面,调用其方法最终都委托到了当前线程的ThreadLocalMap

over~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值