InheritableThreadLocal类详解

2023-11-05

我们在使用ThreadLocal类的时候,可以保证各个线程使用自己的数据,而不相互干扰。

但是如果我们有这样的一个需求,就是各个线程相互不干扰的情况下。各个线程的子线程可以访问到当前线程中的值。对于这个子线程来说就是访问父线程。

public class InheritableThreadLocal<T> extends ThreadLocal<T> {
我们可以从源码中看出InheritableThreadLocal类继承了ThreadLocal这个类。

也就是说,该类具备了ThreadLocal类的能力。

此时我们可以运行一个demo

public class InheritableThreadLocalTest {

    public static void main(String[] args) throws InterruptedException {
        InheritableThreadLocalContext inheritableThreadLocalContext = new InheritableThreadLocalContext();
        inheritableThreadLocalContext.setValue("123");
        System.out.println(inheritableThreadLocalContext.getValue());

    }
}

public class InheritableThreadLocalContext {

    public static ThreadLocal<String> threadLocal = new ThreadLocal<>();
    //可以获取父线程的数据
//    public static InheritableThreadLocal<String> threadLocal = new InheritableThreadLocal<>();
    public void setValue(String s) {
        threadLocal.set(s);
    }

    public String getValue() throws InterruptedException {

        /*

        final String[] s = {null};
        Runnable runnable = () -> s[0] = threadLocal.get();
        Thread t = new Thread(runnable);
        t.start();
        Thread.sleep(1000);
        return s[0];
        */
        return threadLocal.get();
    }
}

我们可以发现,当我在子线程中去访问ThreadLocal对象的值的时候,获取值的时候,是获取不到的。但是我们将ThreadLocal类替换成InheritableThreadLocal类的时候,此时是可以获取到值的。也就是说,在各个不相关的线程不相互干扰的情况下,实现了子线程获取父线程数据的能力。

也就是该InheritableThreadLocal类最大的能力。

我们可以看一看该类的实现。

public class InheritableThreadLocal<T> extends ThreadLocal<T> {
    /**
     * Computes the child's initial value for this inheritable thread-local
     * variable as a function of the parent's value at the time the child
     * thread is created.  This method is called from within the parent
     * thread before the child is started.
     * <p>
     * This method merely returns its input argument, and should be overridden
     * if a different behavior is desired.
     *
     * @param parentValue the parent thread's value
     * @return the child thread's initial value
     */
    protected T childValue(T parentValue) {
        return parentValue;
    }

    /**
     * Get the map associated with a ThreadLocal.
     *
     * @param t the current thread
     */
    ThreadLocalMap getMap(Thread t) {
       return t.inheritableThreadLocals;
    }

    /**
     * Create the map associated with a ThreadLocal.
     *
     * @param t the current thread
     * @param firstValue value for the initial entry of the table.
     */
    void createMap(Thread t, T firstValue) {
        t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
    }
}

这里有两个方法createMap和 getMap。复写了父类ThreadLocal类的方法。有分析过ThreadLocal源码的朋友可以知道。ThraedLocal 对象的值是保存在一个自己实现的Map中的。然后绑定到当前的Thread对象的 threadLocals成员变量上。



这里我们可以看到一个inheritableThreadLocals成员变量。该成员变量是InheritableThreadLocal类用来存储父线程数据用的。稍后我们会提及




这里可以说明了,为什么ThreadLocal类可以保证每个线程访问的数据相互都不干扰,因为数据是绑定在线程对象本身的。

我们再到Thread类的 init方法中去看下

private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize, AccessControlContext acc) {
    if (name == null) {
        throw new NullPointerException("name cannot be null");
    }

//中间忽略一些代码

if (parent.inheritableThreadLocals != null)
    this.inheritableThreadLocals =
        ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
上面代码的意思是如果父线程的InheritableThreadLocals成员变量不为空,将父线程的InheritableThreadLocals成员变量拷贝到当前线程的

InheritableThreadLocals变量上来。而且,在上面我们可以看到InheritableThreadLocal类复写了ThreadLocal类的getMap和createMap方法,故此可以拿到父线程的数据

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

InheritableThreadLocal类详解 的相关文章

  • 在内存中使用 byte[] 创建 zip 文件。 Zip 文件总是损坏

    我创建的 zip 文件有问题 我正在使用 Java 7 我尝试从字节数组创建一个 zip 文件 其中包含两个或多个 Excel 文件 应用程序始终完成 没有任何异常 所以 我以为一切都好 当我尝试打开 zip 文件后 Windows 7 出
  • Java 枚举与创建位掩码和检查权限的混淆

    我想将此 c 权限模块移植到 java 但是当我无法将数值保存在数据库中然后将其转换为枚举表示形式时 我很困惑如何执行此操作 在 C 中 我创建一个如下所示的枚举 public enum ArticlePermission CanRead
  • 为什么 JTables 使 TableModel 在呈现时不可序列化?

    所以最近我正在开发一个工具 供我们配置某些应用程序 它不需要是什么真正令人敬畏的东西 只是一个具有一些 SQL 脚本生成功能并创建几个 XML 文件的基本工具 在此期间 我使用自己的 AbstractTableModel 实现创建了一系列
  • .properties 中的通配符

    是否存在任何方法 我可以将通配符添加到属性文件中 并且具有所有含义 例如a b c d lalalala 或为所有以结尾的内容设置一个正则表达式a b c anything 普通的 Java 属性文件无法处理这个问题 不 请记住 它实际上是
  • 如何在java中将一个数组列表替换为另一个不同大小的数组列表

    我有两个大小不同的数组列表 如何从此替换 ArrayList
  • 从最终实体获取根证书和中间证书

    作为密码学的菜鸟 我每天都会偶然发现一些简单的事情 今天只是那些日子之一 我想用 bouncy castle 库验证 java 中的 smime 消息 我想我几乎已经弄清楚了 但此时的问题是 PKIXparameters 对象的构建 假设我
  • 将流转换为 IntStream

    我有一种感觉 我在这里错过了一些东西 我发现自己做了以下事情 private static int getHighestValue Map
  • 无法创建请求的服务[org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]-MySQL

    我是 Hibernate 的新手 我目前正在使用 Spring boot 框架并尝试通过 hibernate 创建数据库表 我知道以前也问过同样的问题 但我似乎无法根据我的环境找出如何修复错误 休眠配置文件
  • 在 junit 测试中获取 javax.lang.model.element.Element 类

    我想测试我的实用程序类 ElementUtils 但我不知道如何将类作为元素获取 在 AnnotationProcessors 中 我使用以下代码获取元素 Set
  • Eclipse Maven Spring 项目 - 错误

    I need help with an error which make me crazy I started to study Java EE and I am going through tutorial on youtube Ever
  • 帮助将图像从 Servlet 获取到 JSP 页面 [重复]

    这个问题在这里已经有答案了 我目前必须生成一个显示字符串文本的图像 我需要在 Servlet 上制作此图像 然后以某种方式将图像传递到 JSP 页面 以便它可以显示它 我试图避免保存图像 而是以某种方式将图像流式传输到 JSP 自从我开始寻
  • 像 Java 这样的静态类型语言中动态方法解析背后的原因是什么

    我对 Java 中引用变量的动态 静态类型和动态方法解析的概念有点困惑 考虑 public class Types Override public boolean equals Object obj System out println i
  • volatile、final 和synchronized 安全发布的区别

    给定一个带有变量 x 的 A 类 变量 x 在类构造函数中设置 A x 77 我们想将 x 发布到其他线程 考虑以下 3 种变量 x 线程安全 发布的情况 1 x is final 2 x is volatile 3 x 设定为同步块 sy
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • 如何对不同的参数类型使用相同的java方法?

    我的问题 我有 2 个已定义的记录 创建对象请求 更新对象请求 必须通过实用方法进行验证 由于这两个对象具有相同的字段 因此可以对这两种类型应用相同的验证方法 现在我只是使用两种方法进行重载 但它很冗长 public record Crea
  • java for windows 中的文件图标叠加

    我正在尝试像 Tortoise SVN 或 Dropbox 一样在文件和文件夹上实现图标叠加 我在网上查了很多资料 但没有找到Java的解决方案 Can anyone help me with this 很抱歉确认您的担忧 但这无法在 Ja
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • 专门针对 JSP 的测试驱动开发

    在理解 TDD 到底是什么之前 我就已经开始编写测试驱动的代码了 在没有实现的情况下调用函数和类可以帮助我以更快 更有效的方式理解和构建我的应用程序 所以我非常习惯编写代码 gt 编译它 gt 看到它失败 gt 通过构建其实现来修复它的过程
  • Opencv Java 灰度

    我编写了以下程序 尝试从彩色转换为灰度 Mat newImage Imgcodecs imread q1 jpg Mat image new Mat new Size newImage cols newImage rows CvType C
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db

随机推荐

  • 曝光:超级实习生们的训练不一般

    有同学反映在面试华为时 总共四面 到技术面的时候被毙掉了 而且短时间内不能进行二次投递 这就非常的痛苦 虽然现在网上有很多的面试资料 其中不乏一些干货精华 但是只收藏不会用或者只会背八股文 面试时会非常被动 在面试中 动手编程能力是最重要的
  • vue3加载element-plus,修改端口

    环境 最新的node js 最新的vue 安装element plus npm i element plus save legacy peer deps 加载element plus 之前的vue2的方法不适用 import Element
  • 外包三年半,人废了一半

    如果不是女朋友和我提分手 我估计现在还没醒悟 大专生 18年通过校招进入湖南某软件公司 干了3年多的CRUD 今年年初 感觉自己不能够在这样下去了 长时间呆在一个舒适的环境会让一个人堕落 而我已经在一个企业干了3年的CRUD 已经让我变得不
  • VUE+Element UI 展示json数据 [vue-json-viewer]

    1 安装组件vue json viewer npm install vue json viewer save 2 在main js中引入并使用vue json viewer import JsonViewer from vue json v
  • linux下安装git-lfs的两种方法

    一 方法一 推荐 首先安装git lfs ubuntu版 sudo apt get install git lfs centeros版 sudo yum install git lfs 然后验证安装成功 git lfs install 若显
  • 电商平台学习笔记(四)——Spring配置Mybatis简化DAO层省略Mybatis核心配置文件

    今天看到电商视频教程第三天的时候 惊奇的发现 这个电商平台一共有16张表 加上MyBatis的模板Bean 一共32个Bean 如下图 想到这里 如果有Mybatis的核心配置文件 mybatis config xml 仅对每一JavaBe
  • Java中匿名内部类

    含义 由于Java中接口和抽象类都不能实例化对象 故使用接口或抽象类时 必须有一个实现类 对应接口 或继承类 对应抽象类 而该实现类或继承类的对象被使用次数很少 不值得去专门编码时候 就可以使用匿名内部类 此时该类不必命名 并且对象只被创建
  • 4.7、漏洞利用-SMTP

    目录 4 7 漏洞利用 SMTP 1 SMTP环境搭建 1 1 邮件发送和接收模型 1 2 添加主机名和域名 1 3 Ubuntu下安装postfix 1 4 安装dovcot 2 利用搭建环境发送和接收邮件 3 枚举smtp用户名 3 2
  • secure注册码&许可向导

    secure许可向导搜了半天也没找到能用的 搜注册码一搜就搜到了 Name meisi Company TEAM ZWT Serial Number 03 14 367662 License Key ACCFAX R9FHJ7 QZVS2P
  • 适合零基础学习的IT编程技术

    现在很多应届生 不管是否是计算机专业 都想毕业后从事IT行业 不仅是因为IT行业的薪资高 更主要是IT行业就业需求多 发展好 工作稳定 学IT 技术在手 天下我走 当然 IT行业有很多学科方向 学习哪个方向很重要 选择方向这件事 有时候就是
  • Lenet5实现及代码详解——以MINST数据集为例

    看了卷积神经网络 CNN 的原理及介绍 想着自己动手解决一个案例 在网上也看了很多博客 这里整理一下 顺便记录一下自己解决一个完成的CNN实例的过程 以便以后方便看 如果有不足之处 欢迎大家指正 数据获取与可视化操作 1 下载minst数据
  • Android Audio系统框架

    Audio System 二 之 Audio系统框架 二 Linux Audio系统框架 2 1 Application 层 2 2 Framework 层 2 3 Libraries 层 2 4 HAL 层 2 5 Tinyalsa 层
  • vue3 Failed to resolve component router-view

    Failed to resolve component router view If this is a native custom element make sure to exclude it from component resolu
  • unity常用核心类

    Transform 变换 主要用于控制物体的旋转 移动 缩放 Rotate eulerAngles Vector3 relativeTo Space Space Self void 旋转 游戏对象围绕Y轴旋转 transform Rotat
  • JqGrid实现分页相关

    jqGrid默认就提供了分页的功能 其在实现分页的时候有两个隐含的属性与后台交互及page 当前页 rows 每页显示的数据量 当请求下一页的时候请求数据头部默认包含这两个属性 如图 Page和rows传到后台 后台接收 要实现分页后台必须
  • unity 获取场景所有物体

    转载的 Unity 遍历场景所有物体 包括隐藏及被禁用的物体 用于获取所有Hierarchy中的物体 包括被禁用的物体 private List
  • mysql增加用户

    mysql增加用户 增加用户 注意 和上面不同 下面的因为是MYSQL环境中的命令 所以后面都带一个分号作为命令结束符 格式 grant select on 数据库 to 用户名 登录主机 identified by 密码 第一种 增加一个
  • CM5501高效四开关降压-升压控制器(升降压芯片)

    CM5501 High Efficiency 4 Switch Buck Boost Controller Description CM5501 is a synchronous 4 switch Buck Boost controller
  • elasticsearch-索引与分片实现原理

    添加索引 我们往 Elasticsearch 添加数据时需要用到 索引 保存相关数据的地方 索引实际上是指向一个或者多个物理 分片 的逻辑命名空间 一个 分片 是一个底层的 工作单元 它仅保存了全部数据中的一部分 在分片内部机制中 我们将详
  • InheritableThreadLocal类详解

    我们在使用ThreadLocal类的时候 可以保证各个线程使用自己的数据 而不相互干扰 但是如果我们有这样的一个需求 就是各个线程相互不干扰的情况下 各个线程的子线程可以访问到当前线程中的值 对于这个子线程来说就是访问父线程 public