ThreadLocal原理总结(建议收藏观看)

简介: 声明:本⽂使⽤的是JDK 1.8⾸先我们来看⼀下JDK的⽂档介绍:

⼀、什么是ThreadLocal

声明:本⽂使⽤的是JDK 1.8

⾸先我们来看⼀下JDK的⽂档介绍:

结合我的总结可以这样理解:ThreadLocal提供了线程的局部变量,每个线程都可以通过 set() 和get() 来对这个局部变量进⾏操作,但不会和其他线程的局部变量进⾏冲突,实现了线程的数据隔离简要⾔之:往ThreadLocal中填充的变量属于当前线程,该变量对其他线程⽽⾔是隔离的。

⼆、为什么要学习ThreadLocal?

从上⾯可以得出:ThreadLocal可以让我们拥有当前线程的变量,那这个作⽤有什么⽤呢???

2.1管理Connection

最典型的是管理数据库的Connection:当时在学JDBC的时候,为了⽅便操作写了⼀个简单数据库连接

池,需要数据库连接池的理由也很简单,频繁创建和关闭Connection是⼀件⾮常耗费资源的操作,因此需要创建数据库连接池~

那么,数据库连接池的连接怎么管理呢??我们交由ThreadLocal来进⾏管理。为什么交给它来管理呢??ThreadLocal能够实现当前线程的操作都是⽤同⼀个Connection,保证了事务!

当时候写的代码:

同样的,Hibernate对Connection的管理也是采⽤了相同的⼿法(使⽤ThreadLocal,当然了Hibernate的实现是更强⼤的)

2.2避免⼀些参数传递

避免⼀些参数的传递的理解可以参考⼀下Cookie和Session:

每当我访问⼀个⻚⾯的时候,浏览器都会帮我们从硬盘中找到对应的Cookie发送过去。浏览器是⼗分聪明的,不会发送别的⽹站的Cookie过去,只带当前⽹站发布过来的Cookie过去浏览器就相当于我们的ThreadLocal,它仅仅会发送我们当前浏览器存在的Cookie(ThreadLocal的局部变量),不同的浏览器对Cookie是隔离的(Chrome,Opera,IE的Cookie是隔离的【在Chrome登陆了,在IE你也得重新登陆】),同样地:线程之间ThreadLocal变量也是隔离的....

那上⾯避免了参数的传递了吗??其实是避免了。Cookie并不是我们⼿动传递过去的,并不需要写

<input name= cookie/> 来进⾏传递参数...

在编写程序中也是⼀样的:⽇常中我们要去办理业务可能会有很多地⽅⽤到身份证,各类证件,每次我

们都要掏出来很麻烦

⽽如果⽤了ThreadLocal的话,ThreadLocal就相当于⼀个机构,ThreadLocal机构做了记录你有那么多张证件。⽤到的时候就不⽤⾃⼰掏了,问机构拿就可以了。

在咨询时的时候就告诉机构:来,把我的身份证、房产证、学⽣证通通给他。在办理时⼜告诉机构:来,把我的身份证、房产证、学⽣证通通给他。...

这样是不是⽐⾃⼰掏⽅便多了。

当然了,ThreadLocal可能还会有其他更好的作⽤,如果知道的同学可在评论留⾔哦~~~

三、ThreadLocal实现的原理

想要更好地去理解ThreadLocal,那就得翻翻它是怎么实现的了~

⾸先,我们来看⼀下ThreadLocal的set()⽅法,因为我们⼀般使⽤都是new完对象,就往⾥边set对象了

上⾯有个ThreadLocalMap,我们去看看这是什么?

通过上⾯我们可以发现的是ThreadLocalMapThreadLocal的⼀个内部类。⽤Entry类来进⾏存储

我们的值都是存储到这个Map上的,key是当前ThreadLocal对象!

如果该Map不存在,则初始化⼀个:

如果该Map存在,则从Thread中获取!

Thread维护了ThreadLocalMap变量

从上⾯⼜可以看出,ThreadLocalMap是在ThreadLocal中使⽤内部类来编写的,但对象的引⽤是在

Thread中!

于是我们可以总结出:Thread为每个线程维护了ThreadLocalMap这么⼀个Map,⽽ThreadLocalMapkeyLocalThread对象本身,value则是要存储的对象有了上⾯的基础,我们看get()⽅法就⼀点都不难理解了:

3.1ThreadLocal原理总结

1. 每个Thread维护着⼀个ThreadLocalMap的引⽤

2. ThreadLocalMap是ThreadLocal的内部类,⽤Entry来进⾏存储

3. 调⽤ThreadLocal的set()⽅法时,实际上就是往ThreadLocalMap设置值,key是ThreadLocal对

象,只是传递进来的对象

4. 调⽤ThreadLocal的get()⽅法时,实际上就是往ThreadLocalMap获取值,key是ThreadLocal对象

5. ThreadLocal本身并不存储值,它只是作为⼀个key来让线程从ThreadLocalMap获取value

正因为这个原理,所以ThreadLocal能够实现“数据隔离”,获取当前线程的局部变量值,不受其他线程

影响

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

相关文章
|
Java Spring 容器
Spring的AOP失效场景详解
Spring的AOP失效场景详解
1806 0
|
11月前
|
监控 Java 应用服务中间件
SpringBoot是如何简化Spring开发的,以及SpringBoot的特性以及源码分析
Spring Boot 通过简化配置、自动配置和嵌入式服务器等特性,大大简化了 Spring 应用的开发过程。它通过提供一系列 `starter` 依赖和开箱即用的默认配置,使开发者能够更专注于业务逻辑而非繁琐的配置。Spring Boot 的自动配置机制和强大的 Actuator 功能进一步提升了开发效率和应用的可维护性。通过对其源码的分析,可以更深入地理解其内部工作机制,从而更好地利用其特性进行开发。
463 6
|
5月前
|
druid Java 应用服务中间件
五大主流数据库连接池的深度剖析与对比
HikariCP通过优化concurrentBag和fastStatementList等集合,提升了并发的读写效率。它采用threadlocal缓存连接,并大量运用CAS机制,以最大程度地减少lock的使用。从字节码的维度进行代码优化,确保方法尽量控制在35个字节码以内,以提升JVM处理效率。HikariCP在此基础上的进一步优化措施包括:利用ping命令进行mysql连接,以及通过Sharding-JDBC的Driver、Server和Sidecar三个版本,构建灵活多样的生态系统,满足不同需求和环境。对于线上应用,Sharding-JDBC-Driver可提供直连数据库的最优性能,而Sha
|
10月前
|
机器学习/深度学习 人工智能 PyTorch
DeepSeek开源周第四弹之一!DualPipe:训练V3/R1的双向流水线并行技术,计算与训练完全重叠,训练效率提升200%
DeepSeek 开源的 DualPipe 技术通过双向流水线并行设计,显著提升大规模深度学习模型的训练效率,优化计算与通信重叠,降低内存峰值需求,适用于推理加速、多模态数据处理等场景。
766 1
DeepSeek开源周第四弹之一!DualPipe:训练V3/R1的双向流水线并行技术,计算与训练完全重叠,训练效率提升200%
|
存储 算法 安全
深入详解ThreadLocal
在我们日常的并发编程中,有一种神奇的机制在静悄悄地为我们解决着各种看似棘手的问题,它就是 ThreadLocal 。
21796 9
深入详解ThreadLocal
|
存储 安全 Java
AQS为什么采用双向链表
AQS为什么采用双向链表
360 10
|
计算机视觉
【YOLOv8改进】动态蛇形卷积(Dynamic Snake Convolution)用于管状结构分割任务
YOLO目标检测专栏介绍了DSCNet,它针对血管和道路等管状结构的分割任务进行优化。DSCNet采用动态蛇形卷积(DSConv)聚焦细长结构,多视角融合策略增强全局形态理解,且通过持久同调的连续性约束损失改善拓扑连续性。DSConv在2D和3D数据集上表现优于传统方法,实现更高精度和连续性。该技术已应用于yolov8,提升对管状结构的检测效果。
【多线程面试题十六】、谈谈ReentrantLock的实现原理
这篇文章解释了`ReentrantLock`的实现原理,它基于Java中的`AbstractQueuedSynchronizer`(AQS)构建,通过重写AQS的`tryAcquire`和`tryRelease`方法来实现锁的获取与释放,并详细描述了AQS内部的同步队列和条件队列以及独占模式的工作原理。
【多线程面试题十六】、谈谈ReentrantLock的实现原理
|
存储 安全 Java
深入理解Java中的ThreadLocal机制:原理、方法与使用场景解析
深入理解Java中的ThreadLocal机制:原理、方法与使用场景解析
536 2
|
存储 SQL 数据管理
基于阿里云数据库 SelectDB 版内核 Apache Doris 全新分区策略 Auto Partition 应用场景与功能详解
自动分区的出现进一步简化了复杂场景下的 DDL 和分区表的维护工作,许多用户已经使用该功能简化了工作流程,并且极大的便利了从其他数据库系统迁移到 Doris 的工作,自动分区已成为处理大规模数据和应对高并发场景的理想选择。
543 0