广告
返回顶部
首页 > 资讯 > 后端开发 > Python >JavaInheritableThreadLocal用法详细介绍
  • 772
分享到

JavaInheritableThreadLocal用法详细介绍

2024-04-02 19:04:59 772人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录简介问题复现解决方案源码分析注意简介 本文介绍InheritableThreadLocal的用法。 ThreadLocal可以将数据绑定当前线程,如果希望当前线程的ThreadL

简介

本文介绍InheritableThreadLocal的用法。

ThreadLocal可以将数据绑定当前线程,如果希望当前线程的ThreadLocal的数据被子线程使用,实现方式就会相当困难(需要用户自己在代码中传递)。

InheritableThreadLocal可以方便地让子线程自动获取父线程ThreadLocal的数据。

ThreadLocal和InheritableThreadLocal都要注意,用完后要调用其remove()方法,不然可能导致内存泄露或者产生脏数据。

问题复现

代码

package com.example.a;
public class Demo {
    private static ThreadLocal<String> threadLocal = new ThreadLocal<>();
    public static void main(String[] args) {
        threadLocal.set("hello");
        System.out.println("主线程获取的value:" + threadLocal.get());
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                String value = threadLocal.get();
                System.out.println("子线程获取的value:" + value);
                // 一定要remove,不然可能导致内存泄漏
                threadLocal.remove();
            }
        });
        thread.start();
    }
}

结果(子线程无法获取父线程设置的值)

主线程获取的value:hello
子线程获取的value:null

解决方案

只需要将ThreadLocal变成InheritableThreadLocal。

代码

package com.example.a;
public class Demo {
    private static InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();
    public static void main(String[] args) {
        inheritableThreadLocal.set("hello");
        System.out.println("主线程获取的value:" + inheritableThreadLocal.get());
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                String value = inheritableThreadLocal.get();
                System.out.println("子线程获取的value:" + value);
                // 一定要remove,不然可能导致内存泄漏
                inheritableThreadLocal.remove();
            }
        });
        thread.start();
    }
}

结果(子线程可以获取父线程设置的值)

主线程获取的value:hello
子线程获取的value:hello

源码分析

源码查看

InheritableThreadLocal的源代码:

package java.lang;
import java.lang.ref.*;
public class InheritableThreadLocal<T> extends ThreadLocal<T> {
    protected T childValue(T parentValue) {
        return parentValue;
    }
    ThreadLocalMap getMap(Thread t) {
       return t.inheritableThreadLocals;
    }
    void createMap(Thread t, T firstValue) {
        t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
    }
}

这个类继承了ThreadLocal,并且重写了getMap和createMap方法,区别是:InheritableThreadLocal将 ThreadLocal 中的 threadLocals 换成了 inheritableThreadLocals,这两个变量都是ThreadLocalMap类型,并且都是Thread类的属性。

InheritableThreadLocal为什么能拿到父线程中的ThreadLocal值?

1.InheritableThreadLocal的get方法

InheritableThreadLocal获取值先调用了get方法,所以我们直接看看get方法都做了些啥。

  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();
    }

可以看出,get方法和ThreadLocal中是一样的,唯一有区别的就是其中的getMap方法重写了,返回的是inheritableThreadLocals属性。这个属性也是一个ThreadLocalMap类型的变量。那么可以推断:是在某处将父线程中的ThreadLocal值赋值到了子线程的inheritableThreadLocals中。

2.子线程inheritableThreadLocals的赋值过程

private void init(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }
        this.name = name.toCharArray();
        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            if (security != null) {
                g = security.getThreadGroup();
            }
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }
        g.checkAccess();
        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }
        g.addUnstarted();
        this.group = g;
        this.daemon = parent.isDaemon();
        this.priority = parent.getPriority();
        if (security == null || isCCLOverridden(parent.getClass()))
            this.contextClassLoader = parent.getContextClassLoader();
        else
            this.contextClassLoader = parent.contextClassLoader;
        this.inheritedAccessControlContext =
                acc != null ? acc : AccessController.getContext();
        this.target = target;
        setPriority(priority);
        //1. 这边先判断了父线程中inheritableThreadLocals属性是否为空,不为空的话就复制给子线程
        if (parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        
        this.stackSize = stackSize;
        
        tid = nextThreadID();
    }

注意

一旦子线程被创建以后,再操作父线程中的ThreadLocal变量,那么子线程是不能感知的。因为父线程和子线程还是拥有各自的ThreadLocalMap,只是在创建子线程的“一刹那”将父线程的ThreadLocalMap复制给子线程,后续两者就没啥关系了。

其他网址传送门

到此这篇关于Java InheritableThreadLocal用法详细介绍的文章就介绍到这了,更多相关Java InheritableThreadLocal内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaInheritableThreadLocal用法详细介绍

本文链接: https://www.lsjlt.com/news/168486.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaInheritableThreadLocal用法详细介绍
    目录简介问题复现解决方案源码分析注意简介 本文介绍InheritableThreadLocal的用法。 ThreadLocal可以将数据绑定当前线程,如果希望当前线程的ThreadL...
    99+
    2022-11-13
  • Python torch.onnx.export用法详细介绍
    目录函数原型参数介绍mode (torch.nn.Module, torch.jit.ScriptModule or torch.jit.ScriptFunction)args (t...
    99+
    2022-11-11
  • Java 方法(详细介绍)
    那么什么是方法呢?Java方法是语句的集合,它们在一起执行一个功能。 (推荐学习:java课程)方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在程序中被创建,在其他地方被引用方法的优点 使程序变得更...
    99+
    2017-06-19
    java教程 Java
  • fastjson 使用方法详细介绍
    Fastjson介绍Fastjson是一个Java语言编写的JSON处理器。遵循http://json.org标准,为其官方网站收录的参考实现之一。功能qiang打,支持JDK的各种类型,包括基本的JavaBean、Collection、M...
    99+
    2023-05-30
    fastjson 使用
  • Android ADB详细介绍及用法
    Android ADB 用法 adb  全称是 Android Debug Bridge, 就是起到调试桥的作用。 用来操作android设备的 阅读目录 ad...
    99+
    2022-06-06
    adb Android
  • Android onCreate( )方法详细介绍
    onCreate( )方法是android应用程序中最常见的方法之一,那么,我们在使用onCreate()方法的时候应该注意哪些问题呢?     ...
    99+
    2022-06-06
    方法 Android
  • JSON基础介绍与详细用法
    一、什么是JSON 1、JSON指的是JavaScript对象表示法(JavaScript Object Notation)。2、JSON是轻量级的文本数据交换格式,比XML更小、更...
    99+
    2022-11-13
  • 详细介绍Github的使用方法
    随着互联网技术的不断发展,越来越多的开发者开始加入到开源项目中,Github作为目前全球最大的代码托管平台之一,也成为了开发者们分享、学习、合作的重要工具之一。然而,如何使用Github来进行代码管理、版本控制、协作开发等,还是很多新手开发...
    99+
    2023-10-22
  • Vuex详细介绍和使用方法
    目录一、什么是Vuex二、运行机制三、创建项目1、使用脚手架搭建Vue项目2、安装Vuex3、启动项目4、配置使用Vuex4.1、创建store文件夹4.2、配置全局使用store对...
    99+
    2022-11-13
  • 详细介绍HTML的基本用法
    HTML是一种基本的网页设计语言,是创建网页的重要工具之一。对于想要学习HTML的初学者来说,了解HTML的基本用法是至关重要的。本文将详细介绍HTML的基本用法,让你轻松入手。一、HTML的基本概念HTML,全称是HyperText Ma...
    99+
    2023-05-14
  • React Immutable使用方法详细介绍
    目录1. 介绍2. 优缺点3. 对象处理4. 数组处理5. 优化组件渲染6. immutable和redux集合使用1. 介绍 假设当前 redux 的大小为 1G,现在要修改 re...
    99+
    2022-11-13
  • OAuth2 详细介绍!
    目录 一、文章介绍 二、OAth2 2.1 简介 2.2 OAuth2  授权总体流程 2.3 四种授权模式 1.授权码模式 2.简化模式 3.密码模式 4. 客户端模式 2.4 OAuth2 标准接口 2.5 GitHub 授权登录 1...
    99+
    2023-09-15
    github java
  • springMVC详细介绍
    目录springMVC简介SpringMVC框架的优点第一个SpringMVC程序第一步:创建maven-web项目第二步:在pom.xml中添加依赖和插件第三步注册中央调度器第四步...
    99+
    2022-11-12
  • DockerCompose详细介绍
    目录一、Docker Compose的安装二、Docker Compose的基本使用三、Docker Compose的高级功能四、总结一、Docker Compose的安装 Dock...
    99+
    2023-05-16
    Docker Compose详解 Docker Compose
  • Mysql优化方法详细介绍
    目录1、字段属性2、字段NOT NULL3、JOIN代替子查询4、UNION代替手动创建临时表5、事务6、索引下面聊聊mysql常见的优化方法。 1、字段属性 mysql是一...
    99+
    2023-02-03
    Mysql优化 Mysql优化方法
  • Kotlin 基础语法详细介绍
    Kotlin 基础语法详细介绍基础语法定义包名包名的定义应当在源文件的头部package my.demoimport java.util.*// ......
    99+
    2023-05-31
    kotlin 基础语法
  • Android Service中方法使用详细介绍
     service作为四大组件值得我们的更多的关注 在Android中,Activity主要负责前台页面的展示,Service主要负责需要长期运行的任务。例如,一个从s...
    99+
    2022-06-06
    android service service 方法 Android
  • Android 调试工具用法详细介绍
    本文主要为大家讲解多种Android调试工具的用法。        1. 查看当前堆栈   &n...
    99+
    2022-06-06
    调试 工具 Android
  • 详细介绍python类及类的用法
    目录一、类的成员1.1 类的属性1.1.1 静态属性的创建方式1.1.2 实例属性1.2 类的方法二、类成员的修饰符三、类的特殊成员3.1 __doc__3.2  ...
    99+
    2022-11-12
  • Python列表list的详细用法介绍
    目录一. 创建列表1.1 第一种1.2 第二种二. 查询列表2.1 获取列表元素索引2.2 获取列表单个元素2.3 获取列表多个元素2.3 判断元素是否存在于列表三. 列表添加操作四...
    99+
    2022-11-11
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作