ThredLocal的底层原理

简介: ThredLocal的底层原理

ThreadLocal是什么?


ThreadLocal是一种线程隔离机制,它提供多线程环境下对于共享变量访问的一个安全性,在多线程访问功效变量这一个场景里面


image.png

如图,一般情况下我们解决办法对于共享变量去加锁,所以保证在同一个时刻,只有一个线程能够对共享变量进行更新,并且基于Happens-Before规则里面的一个锁监视器的一个规则,又能够保证数据修改之后,对于其他线程是可见的

image.png但是加锁呢,会带来一个性能上的下降,所以ThreadLocal用了一种换时间的一个设计思想,在每个线程里面都有一个容器,来存储共享变量的一个副本,然后每个线程只对自己的变量副本来做更新操作,这样的话既解决了线程的安全问题,又避免了多线程竞争锁的一个开销



ThredLocal实现原理


image.png

ThreadLocal是在Thread类里面有一个成员变量叫ThreadLocalMap它专门用来存储当前线程的共享变量的一个副本,后续这个线程对共享变量的一个操作,都是从ThreadLocalMap里面来进行变更的,不会影响全局共享变量的一个值,从而会实现数据一个隔离



Java 中有4种引用


  1. 强引用是使用最普遍的引用。如果一个对象具有强引用,那 垃圾回收器绝不会回收它,当 内存空间不足时, Java 虚拟机宁愿抛出 OutOfMemoryError 错误,使程序 异常终止,也不会靠随意 回收具有 强引用的 对象来解决内存不足的问题。


  1. 如果一个对象只具有 软引用,则 内存空间充足时, 垃圾回收器就 不会回收它;如果 内存空间不足了,就会 回收这些对象的内存。


  1. 弱引用与 软引用的区别在于:只具有 弱引用的对象拥有 更短暂的 生命周期。在垃圾回收器线程扫描内存区域时,一旦发现了只具有 弱引用的对象,不管当前 内存空间足够与否,都会 回收它的内存。不过,由于垃圾回收器是一个 优先级很低的线程,因此 不一定会 很快发现那些只具有 弱引用的对象。


  1. 虚引用顾名思义,就是 形同虚设。与其他几种引用都不同, 虚引用并 不会决定对象的 生命周期。如果一个对象 仅持有虚引用,那么它就和 没有任何引用一样,在任何时候都可能被垃圾回收器回收。




为什么 ThreadlocalMap 中 key 设计成弱引用类型吗?


image.png

private static final ThreadLocal<UserInfo> userInfoThreadLocal = new ThreadLocal<>();
userInfoThreadLocal.set(userInfo);


这里的引用关系是 userInfoThreadLocal 引用了 ThreadLocal 对象,这是个强引用。 ThreadLocal 对象同时也被 ThreadlocalMap 的 key 引用,这是个 弱引用,我们前面说 GC 要回收 ThreadLocal 对象的前提是它只被 弱引用,没有任何强引用,一旦一个对象只被弱引用引用,GC 的时候就会回收这个对象,所以只要 ThreadLocal 对象如果还被 userInfoThreadLocal(强引用) 引用着,GC 是不会回收被 弱引用的对象的。


ThreadLocal 的设计者考虑到线程往往生命周期很长,比如经常会用到线程池,线程一直存活着,根据 JVM 根搜索算法,一直存在 Thread -> ThreadLocalMap -> Entry(元素)这样一条引用链路, 如下图,如果 key 不设计成 WeakReference 类型,是强引用的话,就一直不会被 GC 回收,key 就一直不会是 null,不为 null Entry 元素就不会被清理(ThreadLocalMap 是根据 key 是否为 null 来判断是否清理 Entry



如果 Threadlocal 对象一直有强引用怎么办


最佳实践是用完手动调用 remove 函数。



ThredLocal实现场景


数据库的连接的一个隔离,客户端请求会话隔离。



相关文章
|
存储 编译器 C语言
C语言实现栈和队列【数据结构/初阶】
C语言实现栈和队列【数据结构/初阶】
236 0
|
JSON 小程序 应用服务中间件
微信的接口wxLogin()的返回值都有什么?
【10月更文挑战第4天】微信的接口wxLogin()的返回值都有什么?
1079 1
|
11月前
|
算法
雪花算法反思:订单ID生成的痛点与解决方案
雪花算法(Snowflake Algorithm)因其生成唯一ID的能力而被广泛应用于分布式系统中。然而,随着业务的发展和系统规模的扩大,一些隐藏的问题逐渐浮现。本文将探讨使用雪花算法生成订单ID后可能遇到的挑战,并提供相应的解决方案。
492 2
|
11月前
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
762 8
|
网络协议 安全 网络安全
WireShark 中的数据包捕获和过滤器详解
【8月更文挑战第20天】
1395 0
|
NoSQL Java Redis
Spring Boot与Redisson的集成
Spring Boot与Redisson的集成
|
Java
SpringBoot启动报错:Unable to start LiveReload server【已解决】
SpringBoot启动报错:Unable to start LiveReload server【已解决】
736 0
|
消息中间件 监控 Kafka
查询Kafka集群中消费组(group)信息和对应topic的消费情况
查询Kafka集群中消费组(group)信息和对应topic的消费情况
5830 0
|
Linux C语言 C++
一文搞懂操作系统进程同步的几种机制(含现实案列)
一文搞懂操作系统进程同步的几种机制(含现实案列)