java ThreadLocal 类常用方法源码解析

 更新时间:2023年07月19日 08:38:44   作者:今夜有点儿凉  
这篇文章主要为大家介绍了java ThreadLocal类常用方法源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

以下是 ThreadLocal 类常用方法源码解析:

1. get()

获取当前线程的 ThreadLocal 变量的值。如果变量尚未被当前线程设置,则返回 null。

public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
        }
    }
    return setInitialValue();
}

解释:该方法首先获取当前线程 Thread.currentThread()

然后,调用 getMap(t) 方法获取当前线程的 ThreadLocalMap 对象 map

如果 map 不为 null,表示当前线程已经有一个 ThreadLocalMap,可以尝试获取与当前 ThreadLocal 对象关联的值。

调用 map.getEntry(this) 方法,传入当前 ThreadLocal 对象作为参数,获取与之关联的 Entry 节点 e

如果 e 不为 null,表示找到了与当前 ThreadLocal 对象关联的值。通过强制类型转换将 e.value 转换为泛型类型 T,并将其赋值给 result 变量。

最后,返回 result,即当前线程中与当前 ThreadLocal 对象关联的值。

如果 map 为 null 或者未找到与当前 ThreadLocal 对象关联的值,则调用 setInitialValue() 方法来设置初始值,并返回该值。

总之,get() 方法用于获取当前线程中与当前 ThreadLocal 对象关联的值。它首先获取当前线程的 ThreadLocalMap 对象,然后在该对象中查找与当前 ThreadLocal 对象关联的值。如果找到了值,则返回该值;否则,设置初始值并返回。

2. set(T value)

该方法用于将指定的值 value 关联到当前线程中的当前 ThreadLocal 对象。

public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}

解释:该方法首先获取当前线程 Thread.currentThread()

然后,调用 getMap(t) 方法获取当前线程的 ThreadLocalMap 对象 map

如果 map 不为 null,表示当前线程已经有一个 ThreadLocalMap,可以直接调用 map.set(this, value) 方法将当前 ThreadLocal 对象和指定的值 value 关联起来。

如果 map 为 null,表示当前线程还没有 ThreadLocalMap,需要调用 createMap(t, value) 方法来创建一个新的 ThreadLocalMap 并将其与当前线程关联起来。

总之,set(T value) 方法用于将指定的值关联到当前线程中的当前 ThreadLocal 对象。它首先获取当前线程的 ThreadLocalMap 对象,然后根据是否存在该对象来选择直接设置值或创建新的 ThreadLocalMap 对象。

3. remove()

该方法用于从当前线程的 ThreadLocalMap 中移除与当前 ThreadLocal 对象关联的值。

public void remove() {
    ThreadLocalMap m = getMap(Thread.currentThread());
    if (m != null)
        m.remove(this);
}

解释:该方法首先通过调用 getMap(Thread.currentThread()) 方法获取当前线程的 ThreadLocalMap 对象 m

如果 m 不为 null,表示当前线程有一个 ThreadLocalMap 对象,可以调用 m.remove(this) 方法来移除与当前 ThreadLocal 对象关联的值。

如果 m 为 null,表示当前线程没有 ThreadLocalMap 对象,无需进行任何操作。

总之,remove() 方法用于从当前线程的 ThreadLocalMap 中移除与当前 ThreadLocal 对象关联的值。它首先获取当前线程的 ThreadLocalMap 对象,然后根据是否存在该对象来选择是否进行移除操作。

4. initialValue()

该方法用于提供一个初始值,以便在首次访问 ThreadLocal 对象时使用。

protected T initialValue() {
    return supplier.get();
}

解释:该方法调用了一个 supplier.get() 方法来获取初始值。这里的 supplier 是一个 Supplier<T> 类型的对象,它提供了一个无参数的 get() 方法,用于获取初始值。

通过重写 initialValue() 方法,我们可以自定义初始值的生成逻辑。默认情况下,如果没有手动设置初始值,ThreadLocal 的初始值为 null

总之,initialValue() 方法用于提供一个初始值,在首次访问 ThreadLocal 对象时使用。通过重写该方法,我们可以自定义初始值的生成逻辑。

5. withInitial(Supplier<? extends T> supplier)

该方法用于创建一个具有初始值供应者的 ThreadLocal 对象。

public static &amp;lt;S&amp;gt; ThreadLocal&amp;lt;S&amp;gt; withInitial(Supplier&amp;lt;? extends S&amp;gt; supplier) {
    return new SuppliedThreadLocal&amp;lt;&amp;gt;(supplier);
}

解释:该方法使用提供的 Supplier 对象来创建一个 SuppliedThreadLocal 对象,该对象实现了 ThreadLocal 接口。Supplier 是一个函数式接口,它定义了一个无参数的 get() 方法,用于获取初始值。

通过调用 withInitial(supplier) 方法,我们可以创建一个具有初始值供应者的 ThreadLocal 对象。该供应者将在首次访问 ThreadLocal 对象时生成初始值。

总之,withInitial(Supplier<? extends S> supplier) 方法用于创建一个具有初始值供应者的 ThreadLocal 对象。通过该方法,我们可以方便地指定一个供应者来生成初始值。

6. getMap(Thread t) 

该方法用于获取给定线程 t 对应的 ThreadLocalMap 对象。

ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}

解释:在 ThreadLocal 类中,每个线程都有一个名为 threadLocals 的字段,它是一个 ThreadLocalMap 对象。该字段用于存储线程本地变量的键值对。

在 getMap(Thread t) 方法中,通过访问线程 t 的 threadLocals 字段,直接返回对应的 ThreadLocalMap 对象。

这个方法的作用是为了获取特定线程的 ThreadLocalMap 对象,以便进行后续的操作,比如获取或设置线程本地变量的值。

需要注意的是,getMap(Thread t) 方法是 ThreadLocal 类的内部方法,我们通常不需要直接调用它,而是通过 ThreadLocal 对象的方法间接地访问线程本地变量。

以上是 ThreadLocal 类常用方法的源码和详细解释。这些方法允许您在多线程环境中维护线程本地变量,并提供了获取、设置、移除 ThreadLocal 变量的功能,更多关于ThreadLocal 类常用方法源码解析的资料请关注脚本之家其它相关文章!

相关文章

  • String实例化及static final修饰符实现方法解析

    String实例化及static final修饰符实现方法解析

    这篇文章主要介绍了String实例化及static final修饰符实现方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • SpringMVC中@Valid不起效BindingResult读取不到Error信息

    SpringMVC中@Valid不起效BindingResult读取不到Error信息

    在写SpringMVC项目时,由于要对表单数据进行校验,需要使用@Valid进行校验,但是在进行数据校验时,BindingResult对象无法拦截非法表单数据,result.hasErrors()无论怎么输入都会返回false,本文详细的介绍一下解决方法
    2021-09-09
  • Spring Boot 集成 RocketMQ 全流程指南(从依赖引入到消息收发)

    Spring Boot 集成 RocketMQ 全流程指南(从依赖引入到消息收发

    本文将通过 手动连接 和 配置连接 两种方式,详细讲解如何在 Spring Boot 中集成 RocketMQ,实现消息的同步与异步发送,并提供完整示例代码,感兴趣的朋友一起看看吧
    2025-04-04
  • java实现图片缩放、旋转和马赛克化

    java实现图片缩放、旋转和马赛克化

    这篇文章主要为大家详细介绍了java实现图片缩放、旋转和马赛克化,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • 快速掌握Java8中的Optional

    快速掌握Java8中的Optional

    Optional 是一个容器类,代表一个值存在或不存在,Optional并不是用来替换所有的null,而是为了在设计良好的API中更明确地表达可能缺失的值,这篇文章主要介绍了Java8的Optional及使用,需要的朋友可以参考下
    2023-07-07
  • SpringBoot2.4.2下使用Redis配置Lettuce的示例

    SpringBoot2.4.2下使用Redis配置Lettuce的示例

    这篇文章主要介绍了SpringBoot2.4.2下使用Redis配置Lettuce,Springboot2.4.2下默认使用的就是Lettuce而不是Jedis因此无需在依赖进行排除Jedis,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2022-01-01
  • Bean的自动注入及循环依赖问题

    Bean的自动注入及循环依赖问题

    本文详细介绍了Bean的自动注入及循环依赖,文中通过代码介绍的非常详细,对大家的学习有一定的研究价值,感兴趣的小伙伴可以阅读参考
    2023-03-03
  • Java中的@interface注解使用详解

    Java中的@interface注解使用详解

    这篇文章主要介绍了Java中的@interface注解使用详解,注解@interface不是接口是注解类,在jdk1.5之后加入的功能,使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,需要的朋友可以参考下
    2023-12-12
  • Springboot 手动分页查询分批批量插入数据的实现流程

    Springboot 手动分页查询分批批量插入数据的实现流程

    这篇文章主要介绍了Springboot 手动分页查询分批批量插入数据的实现流程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • 实战讲解Maven安装及基本使用详解

    实战讲解Maven安装及基本使用详解

    这篇文章主要介绍了实战讲解Maven安装及基本使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10

最新评论