加入收藏 | 设为首页 | 会员中心 | 我要投稿 开发网_开封站长网 (http://www.0378zz.com/)- 科技、AI行业应用、媒体智能、低代码、办公协同!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

异步传递数据实现原理

发布时间:2021-04-12 13:06:20 所属栏目:外闻 来源:互联网
导读:ritableThreadLocal是ThreadLocal的子类,本质上就是一个ThreadLocal。 在Thread类中,threadLocals与inheritableThreadLocals都是线程对象私有的,只能通过当前线程对象写入和获取数据,只是Thread会将写入inheritableThreadLocals的数据传递给子线程的inhe

ritableThreadLocal是ThreadLocal的子类,本质上就是一个ThreadLocal。

在Thread类中,threadLocals与inheritableThreadLocals都是线程对象私有的,只能通过当前线程对象写入和获取数据,只是Thread会将写入inheritableThreadLocals的数据传递给子线程的inheritableThreadLocals。

当我们往ThreadLocal或者InheritableThreadLocal写入数据时,写入过程为:

  • 1、ThreadLocal或者InheritableThreadLocal先调用Thread#currentThread静态方法获取当前线程的Thread对象;
  • 2、获取Thread对象的threadLocals或者inheritableThreadLocals;
  • 3、将ThreadLocal或者InheritableThreadLocal对象作为key,将数据写入到当前Thread对象的threadLocals或者inheritableThreadLocals字段中。

因此,Thread的threadLocals与inheritableThreadLocals的key是ThreadLocal或者InheritableThreadLocal实例,value是写入的数据。

关于threadLocals我在前面一篇《反向理解ThreadLocal,或许这样更容易理解》已经详细介绍过了,本篇重点分析inheritableThreadLocals是如何传递给子线程的。

默认情况下,当我们使用new Thread()创建一个线程时,在Thread的构造方法中会通过Thread#currentThread获取当前线程,将当前线程作为新创建线程的父线程,所以就有了父子线程关系。

无论使用哪个重载的构造方法创建Thread,都会在构造方法中调用init方法完成初始化为Thread字段赋值,而init方法中有这样一段代码:nit方法中,由于inheritThreadLocals参数默认为true,所以只要父线程的inheritableThreadLocals字段不为空,就copy一份父线程的inheritableThreadLocals给当前创建的线程对象,这就实现了将父线程的inheritableThreadLocals存储的数据传递给子线程。

使用InheritableThreadLocal我们不得不考虑的问题:内存泄漏。

ThreadLocal.ThreadLocalMap使用数组存储元素,与HashMap不同,它通过开放定址法解决hash冲突,不存在链表,通过动态扩容数组可无限存储元素,数组元素的类型为Entry。

当我们往ThreadLocal.ThreadLocalMap写入一个key-value时,ThreadLocalMap把key和value包装成一个Entry,并通过key的hashcode值计算索引值,将Entry放到数组中。

ThreadLocal.ThreadLocalMap.Entry类的源码如下:

(编辑:开发网_开封站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读