首页 > 作文

java编程ThreadLocal上下传递源码解析

更新时间:2023-04-06 02:36:28 阅读: 评论:0

引导语

threadlocal 提供了一种方式,让在多线程环境下,每个线程都可以拥有自己独特的数据,并且可以在整个线程执行过程中,从上而下的传递。

1、用法演示

可能很多同学没有使用过 threadlocal,我们先来演示下 threadlocal 的用法,demo 如下:

从运行结果中可以看到,key1 对应的值已经从上下文中拿到了。

getfromcomtext 方法是没有接受任何入参的,通过 context.get().get(“key1”) 这行代码就从上下文中拿到了 key1 的值,接下来我们一起来看下 threadlocal 底层是如何实现上下文的传递的。

2、类结构

2.1、类泛型

threadlocal 定义类时带有泛型,说明 threadlocal 可以储存任意格式的数据,源码如下:

2.2、关键属性

threadlocal 有几个关键属性,我们一一看下网络安全保障技术:

还有一个重要属性:threadlocalmap,当一个线程有多个 threadlocal 时,需要一个容器来管理多个 threadlocal,threadlocalmap 的作用就是这个,管理线程中多个 threadlocal。

2.2.1、threadlocalmap

threadlocalmap 本身就是一个简单的 map 结构,key 是 threadlocal,value 是 threadlocal 保存的值,底层是数组的数据结构,源码如下:

从源码中看到 threadlocalmap 其实就是一个简单的 map 结构,底层是数组,有初始化大小,也有扩容阈值大小,数组的元素是 entry,entry 的 key 就是 threadlocal 的引用,value 是 threadlocal 的值。

3、threadlocal 是如何做到线程之间数据隔离的

threadlocal 是线程安全的,我们可以放心使用,主要因为是 threadlocalmap 是线程的属性,我们看下线程 thread 的节约用水宣传语源码,如下:

从上图中,我们可以看到 threadlocals.threadlocalmap 和 inheritablethreadlocals.threadlocalmap 分别是线程的属性,所以每个线程的 threadlocals 都是隔离独享的。

父线程在创建子线程的情况下,会拷贝 inheritablethreadlocals 的值,但不会拷贝 threadlocals 的值,源码如下:

从上图中我们可以看到,在线程创建时,会把父线程的 inheritablethreadlocals 属性值进行拷贝。

4、t 方法

t 方法的主要作用是往当前 threadlocal 里面 t 值,假如当前 threadlocal 的泛型是 map,那么就是往当前 threadlocal 里面 t map,源码如下:

代码逻辑比较清晰,我们在一起来看下 threadlocalmap.t 的源码,如下:

上面源码我们注意几点:

是通过递增的 atomicinteger 作为 threadlocal 的 hashcode 的;计算数组索引位置的公式是:hashcode 取模数组大小,由于 hashcode 不断自增,所以不同的 hashcode 大概率上会计算到同一个数组的索引位置(但这个不用担心,在实际子攻父爱项目中,threadlocal 都很少,基本上不会冲突);通过 hashcode 计算的索引位置 i 处如果已经有值了,会从 i 开始,通过 +1 不断的往后寻找,直到找到索引位置为空的地方,把当前 threadlocal 作为 key 放进去。

好在日常工作中使用 threadlocal 时,常常只使用 1~2 个 threadlocal,通过 hash 计算出重复的数组的概率并不是很大。

t 时的解决数组元素位置冲突的策略,也对 get 方法产生了影响,接着我们一起来看一下木乃伊是怎么形成的 get 方法。

5、get 方法

get 方法主要是从 threadlocalmap 中拿到当前 threadlocal 储存的值,源码如下:

接着我们来看下 threadlocalmap 的 getentry 方法,源码如下:

get 逻辑源码中注释已经写的很清楚了,我们就不重复说了。

6、扩容

threadlocalma抽奖方式p 中的 threadlocal 的个数超过阈值时,threadlocalmap 就要开始扩容了,我们一起来看下扩容的逻辑:

源码注解也比较清晰,我们注意两点:

扩容后数组大小是原来数组的两倍;扩容时是绝对没有线程安全问题的,因为 threadlocalmap 是线程的一个属性,一个线程同一时刻只能对 threadlocalmap 进行操作,因为同一个线程执行业务逻辑必然是串行的,那么操作 threadlocalmap 必然也是串行的。

7、总结

threadlocal 是非常重要的 api,我们在写一个中间件的时候经常会用到,比如说流程引擎中上下文的传递,调用链id的传递等等,非常好用,但坑也很多。

以上就是java编程threadlocal上下传递源码解析的详细内容,更多关于java编程threadlocal上下传递的资料请关注www.887551.com其它相关文章!

本文发布于:2023-04-06 02:36:26,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/40e560b76962bf56827d50ce6f2b434f.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:java编程ThreadLocal上下传递源码解析.doc

本文 PDF 下载地址:java编程ThreadLocal上下传递源码解析.pdf

标签:线程   源码   数组   方法
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图