博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
InheritableThreadLocal类原理简介使用 父子线程传递数据详解 多线程中篇(十八)...
阅读量:6948 次
发布时间:2019-06-27

本文共 2692 字,大约阅读时间需要 8 分钟。

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

测试代码

 

public class T25 {public static void main(String[] args) {//主线程中赋值ThreadLocal
stringThreadLocal = new ThreadLocal<>();InheritableThreadLocal
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而已,然后覆盖了几个方法
 
原文地址:

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

你可能感兴趣的文章
iOS开发个人开发账号的证书详细使用及介绍
查看>>
尺取法
查看>>
Your APP_BUILD_SCRIPT points to an unknown file: ./jni/Android.mk
查看>>
NOIP-珠心算
查看>>
使用crypt配置Basic Auth登录认证
查看>>
sklearn
查看>>
linux命令系列目录
查看>>
sql server 2008学习1–系统数据库
查看>>
sql server08 查询优化系列 3-2 sql 查询性能分析
查看>>
JS 变量
查看>>
访问图像像素信息方式的优化
查看>>
小小笔试题(二)
查看>>
centos7安装python3 以及tab补全功能
查看>>
《Android深入透析》之常用设计模式经验谈
查看>>
leetcode539
查看>>
归并排序实现
查看>>
leetcode91
查看>>
Qt中实现菜单和工具栏功能
查看>>
java相关技术问答(二)
查看>>
网络攻防实验(二)——201521460003王浩洋
查看>>