上一篇文章中对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类原理简介使用 父子线程传递数据详解 多线程中篇(十八)的更多相关文章

  1. Java线程创建形式 Thread构造详解 多线程中篇(五)

    Thread作为线程的抽象,Thread的实例用于描述线程,对线程的操纵,就是对Thread实例对象的管理与控制. 创建一个线程这个问题,也就转换为如何构造一个正确的Thread对象. 构造方法列表 ...

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

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

  3. Thread类详解 多线程中篇(二)

    Java.lang.Thread是Java应用程序员对Java多线程的第一站,Thread就是对Java线程本身的抽象 所以在Java中的线程编程概念中,一个Thread实例 == 一个线程 线程有哪 ...

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

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

  5. Java多线程初学者指南(7):向线程传递数据的三种方法

    在传统的同步开发模式下,当我们调用一个函数时,通过这个函数的参数将数据传入,并通过这个函数的返回值来返回最终的计算结果.但在多线程的异步开发模式下,数据的传递和返回和同步开发模式有很大的区别.由于线程 ...

  6. 深入解析ThreadLocal 详解、实现原理、使用场景方法以及内存泄漏防范 多线程中篇(十七)

    简介 从名称看,ThreadLocal 也就是thread和local的组合,也就是一个thread有一个local的变量副本 ThreadLocal提供了线程的本地副本,也就是说每个线程将会拥有一个 ...

  7. Android事件传递机制详解及最新源码分析——ViewGroup篇

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 在上一篇<Android事件传递机制详解及最新源码分析--View篇>中,详细讲解了View事件的传递机制,没掌握或者掌握不扎实的小伙伴 ...

  8. Android 的事件传递机制,详解

    Android 的事件传递机制,详解 前两天和一个朋友聊天的时候.然后说到事件传递机制.然后让我说的时候,忽然发现说的不是非常清楚,事实上Android 的事件传递机制也是知道一些,可是感觉自己知道的 ...

  9. Android Touch事件传递机制详解 下

    尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38025165 资源下载:http://download.csdn.net/detail/yu ...

随机推荐

  1. BZOJ_1861_[Zjoi2006]Book 书架_splay

    BZOJ_1861_[Zjoi2006]Book 书架_splay 题意: 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在 ...

  2. 快照(Snapshot)技术发展综述

    快照(Snapshot)技术发展综述 刘爱贵 摘要:传统数据备份技术存在备份窗口.恢复时间目标RTO和恢复时间点RPO过长的问题,无法满足企业关键性业务的数据保护需求,因此产生了数据快照技术.本文对快 ...

  3. 在linux服务器之间复制文件和目录命令scp

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  4. Docker的简单实用

    一.docker的常用操作 二.其实用docker search images它就是去hub仓库里面查找:https://hub.docker.com/ 对容器的操作: 搜索镜像:[root@mast ...

  5. 简述RPC原理实现

      前言 架构的改变,往往是因为业务规模的扩张. 随着业务规模的扩张,为了满足业务对技术的要求,技术架构需要从单体应用架构升级到分布式服务架构,来降低公司的技术成本,更好的适应业务的发展. 分布式服务 ...

  6. Java转Ruby【快速入门】

    最近参加实习了,公司的技术栈中需要用到 Ruby 以及 Rails 框架,所以算是开始了踩坑之旅吧.. Ruby 简介 网上的简介要搜都能搜到,具体涉及的包括历史啦之类这里不再赘述,提几个关键词吧: ...

  7. Java注解(一):介绍,作用,思想及优点

    “注解优先于命令模式”-出自<Effective Java> Java 注解,从名字上看是注释,解释.但功能却不仅仅是注释那么简单.注解(Annotation) 为我们在代码中添加信息提供 ...

  8. Google 的 QUIC 华丽转身成为下一代网络协议: HTTP/3.0

    HTTP/2.0 还没有普及,HTTP/3.0 标准就要被制定了. 据 IETF 透露,HTTP-over-QUIC 实验协议将被重命名为 HTTP/3,并成为 HTTP 协议的第三个正式版本. IE ...

  9. 浅谈unity中gamma空间和线性空间

    转载请标明出处:http://www.cnblogs.com/zblade/ 一.概述 很久没有写文章了,今天写一篇对gamma空间和线性空间的个人理解总结,在查阅和学习了各个资料后,算是一个个人笔记 ...

  10. C#开发APP,ToolBar控件在Smobiler中的使用方式【附案例源码】——Smobiler移动开发平台

    控件说明 底部工具栏控件. 效果演示 其他效果 该界面为仿淘宝UI制作的一个简单的UI模板,源码获取方式请拉至文章末尾. 特色属性 属性 属性说明 Direction(相对布局) 容器主轴方向. Fl ...