上一篇文章中对ThreadLocal进行了详尽的介绍,另外还有一个类:
InheritableThreadLocal
他是ThreadLocal的子类,那么这个类又有什么作用呢?

测试代码

public class T25 {public static void main(String[] args) {//主线程中赋值
ThreadLocal<String> stringThreadLocal = new ThreadLocal<>();InheritableThreadLocal<String> stringInheritableThreadLocal = new InheritableThreadLocal<>();stringThreadLocal.set("ThreadLocal string");
stringInheritableThreadLocal.set("InheritableThreadLocal string");//子线程中分别打印两个变量的信息
new Thread(() -> {
System.out.println(
Thread.currentThread().getName() + " ThreadLocal value :" + stringThreadLocal.get());
System.out.println(Thread.currentThread().getName() + " InheritableThreadLocal value :"
+ stringInheritableThreadLocal.get());
}).start();}
}

在上面的测试代码中,主线程中创建了两个变量,类型分别为:ThreadLocal和InheritableThreadLocal
然后在主线程中创建了一个新的线程
在新的线程中,尝试获取他们的值
从打印信息可以看得出来
对于ThreadLocal获取的值为null,而对于InheritableThreadLocal则能够获取到值
结论:
在子线程中,可以获取到父线程的InheritableThreadLocal类型变量的值,而不能获取到ThreadLocal类型变量的值
对于ThreadLocal我们已经有了详尽的分析,在Thread中有一个map,以ThreadLocal类型的变量作为key
在子线程中,get方法自然是获取子线程中的map,很显然,子线程中的map并没有设置任何值,所以初始值null被读取出来
但是,InheritableThreadLocal为什么能够读取出来?

原理分析

在Thread类中,有一个ThreadLocal.ThreadLocalMap类型的变量:inheritableThreadLocals,他的类型同Thread内部的threadLocals变量
在Thread的init方法中,有一段初始化设置(应该还记得,这个init方法是所有的Thread对象创建的必经之路)
下面为部分代码片段拼接
从上面的这个方法可以很清晰的看得到
如果parent的inheritableThreadLocals不是null,那么就会将当前线程的inheritableThreadLocals设置为parent的inheritableThreadLocals
parent是什么?之前也说过了,就是创建这个线程的线程,也就是平时说的父线程
所以说
借助于inheritableThreadLocals,可以实现,创建线程向被创建线程数据传递
看下下面的方法
逻辑很清晰,创建了一个ThreadLocalMap
inheritableThreadLocals就是ThreadLocalMap类型的
简单理解:这个创建的ThreadLocalMap就是根据入参的ThreadLocalMap,拷贝创建一份
小结:
Thread对象,通过内部的
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
维护从父线程(创建该线程的线程)继承而来的数据
原理就是在创建线程时,如果当前线程的inheritableThreadLocals不为null,那么将会复制一份保存在自己的ThreadLocal.ThreadLocalMap inheritableThreadLocals中

InheritableThreadLocal类解析

对比下 下面的两幅图片,上面为Thread中的相关方法
下图为InheritableThreadLocal中的三个方法
很显然,InheritableThreadLocal作为子类,重写了这几个方法

通过对getMap和createMap方法的重写,可以看得出来,只是内部操作的变量发生了变化,从threadLocals转换为inheritableThreadLocals
而对于childValue方法,还记得刚才的构造方法么(看注释called only by createInheritedMap)
也就是说在父线程创建子线程,初始化InheritableThreadLocal时会用到

总结

InheritableThreadLocal的核心概念仍旧是ThreadLocal.ThreadLocalMap以及ThreadLocal
InheritableThreadLocal是 ThreadLocal的子类
在Thread内部通过维护    ThreadLocal.ThreadLocalMap inheritableThreadLocals 进行父子线程数据的传递
而这个数据则是通过在创建Thread对象的时候,借助于内部的init方法,调用createInheritedMap方法,从父线程(当前创建线程)中复制的一份
后续的数据读取解析,则是通过inheritableThreadLocals变量,与内部的那个threadLocals没有什么关系

换个思路理解,他就是另外一个ThreadLocal,假定Thread定义了两个“ThreadLocal“,其中一个在创建线程的时候会从父线程复制一份
只不过从实现上、以及逻辑上,他继承了ThreadLocal而已,然后覆盖了几个方法
原文地址:InheritableThreadLocal类原理简介使用 父子线程传递数据详解 多线程中篇(十七)

转载于:https://www.cnblogs.com/noteless/p/10448283.html

InheritableThreadLocal类原理简介使用 父子线程传递数据详解 多线程中篇(十八)...相关推荐

  1. 线程组ThreadGroup分析详解 多线程中篇(三)

    线程组,顾名思义,就是线程的组,逻辑类似项目组,用于管理项目成员,线程组就是用来管理线程. 每个线程都会有一个线程组,如果没有设置将会有些默认的初始化设置 而在java中线程组则是使用类ThreadG ...

  2. JAVA跨线程传递数据方式总结

    实现跨线程传递数据方式: v1:子线程使用主线程的局部变量 这种当主线程和子线程不在一快儿时就不适用.可以使用JDK原生的InheritableThreadLocal. v2:InheritableT ...

  3. ThreadLocal父子线程传递实现方案

    前言 介绍InheritableThreadLocal之前,假设对 ThreadLocal 已经有了一定的理解,比如基本概念,原理,如果没有,可以参考:ThreadLocal源码分析解密.在讲解之前我 ...

  4. 向线程传递数据与线程用回调方法检索数据

    用回调方法检索数据 /**//*用回调方法检索数据 下面的示例演示了一个从线程中检索数据的回调方法.包含数据和线程方法的类的构造函数也接受代表回调方法的委托: 在线程方法结束前,它调用该回调委托. * ...

  5. pthread_create函数的详细讲解(包括向线程函数传递参数详解)

    pthread_create是UNIX环境创建线程函数 头文件 #include<pthread.h> 函数声明 int pthread_create(pthread_t*restrict ...

  6. Java线程池ThreadPool详解

    Java线程池ThreadPool详解 1. 线程池概述 1.1 线程池简介 1.2 线程池特点 1.3 线程池解决问题 2. 线程池原理分析 2.1 线程池总体设计 2.6 线程池流转状态 2.2 ...

  7. C++11多线程第三篇:线程传参详解,detach()大坑,成员函数做线程参数

    文章目录 3.1 传递临时对象作为线程参数 3.1.1 要避免的陷阱(解释1) 3.1.2 要避免的陷阱(解释2) 3.1.3 总结 3.2 临时对象作为线程参数进一步详解 3.2.1 线程id概念 ...

  8. ***原理详解(中篇)

    本文来自网易云社区. 3. ***工作原理 终于说到***工作原理了,在说这个之前必须先介绍以下普通socks 5的工作原理,将之与***的"变异版"进行对比,就可以看出***处理 ...

  9. async spring 默认线程池_Spring boot注解@Async线程池实例详解

    这篇文章主要介绍了Spring boot注解@Async线程池实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 从Spring3开始提供了@A ...

最新文章

  1. 资源贴|吴恩达新课发布第1天,3万人观看 | 完整PPT
  2. iOS - 数据的归档和反归档
  3. SDH光端机的应用介绍
  4. Linux系统更新最新版R语言方法
  5. 2020年市场最缺什么_2020年聚合氯化铝市场评述
  6. Java 异常练习
  7. 泛海精灵软件预发布统计报告 反馈
  8. SpringBoot2.1.5 (35)---安全
  9. Python+OpenGL进行立方体多纹理映射
  10. S5PV210-uboot移植-从三星官方uboot开始移植
  11. js控制layui radio button选中
  12. react navigation传值给上一页面
  13. 一线算法工程师总结:python常用数据挖掘算法PDF版
  14. 显卡天梯图2022最新排名
  15. 明争暗斗 京东阿里智能家居大战一触即发
  16. 网页制作html山鸡,做一个简单的html网页
  17. 免费开源的智能家居系统,SpringBoot+Vue前后端分离,WiFi智能设备接入,手把手开发安卓APP,建立QQ智能管家机器人!
  18. 产品的概念:提出与筛选--第三章人人都是产品经理
  19. win10的怎么调计算机亮度,Win10系统调节屏幕亮度的三种方法【图文】
  20. 关于网络、交换机、路由器

热门文章

  1. 2019计算机应用基础期末考试试题,2019-2020年度公共课计算机应用基础考试试题附答案...
  2. python中number函数_Python 数字(Number)
  3. IIS7批量FTP客户端工具软件
  4. php生成文章页,php结合smarty生成静态页面php文章内分页代码
  5. list 释放 java_Java --list 常用方法汇总一
  6. 监控linux终端键盘输入,Linux内核实时监控键盘输入
  7. linux 网络状态图,linux的网络连接状态
  8. 影视双端app源码对接苹果CMS 带商城系统投屏选集直播盒子码支付
  9. 了解快照隔离和行版本控制
  10. HTML5: 全局属性