ThreadLocal精讲

news/2024/11/23 2:01:00/

🍓 简介:java系列技术分享(👉持续更新中…🔥)
🍓 初衷:一起学习、一起进步、坚持不懈
🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏
🍓 希望这篇文章对你有所帮助,欢迎点赞 👍 收藏 ⭐留言 📝

🍓 更多文章请点击
在这里插入图片描述在这里插入图片描述

文章目录

  • 一、什么是ThreadLocal?
  • 二、源码分析
    • 1. 首先看下Thread类
    • 2. ThreadLocalMap这是什么?
    • 3. ThreadLocal详解
  • 三、什么是弱引用呢?
    • 3.1 谈谈引用关系都有哪些,区别又是什么?
    • 3.2 ThreadLocal为何使用弱引用
    • 3.3 内存泄漏是什么,如何避免TheadLocal的内存泄漏?
  • 四、总结

是的

一、什么是ThreadLocal?

  • ThreadLocal用来提供线程级别变量,变量只对当前线程见,ThreadLocal通过空间换时间的方案,规避了竞争问题,因为每个线程都有属于自己的变量。
  • TheadLocal为每个使用该变量的线程单独提供独立的变量副本,具有线程隔离效果。
  • 与synchronized的区别
    synchronized 与 TheadLocal都可以实现多线程访问,保证线程安全问题。
    • synchronized 采用当多线程竞争到同一个资源的时候,最终只能够有一个线程访问,采用时间换空间的方式,保证安全问题。
    • TheadLocal 在每个线程中都自己独立的局部变量,空间换时间,相互之间隔离,相比来说TheadLocal效率更高

在这里插入图片描述

二、源码分析

1. 首先看下Thread类

public class Thread implements Runnable {/* ThreadLocal values pertaining to this thread. This map is maintained* by the ThreadLocal class. */ThreadLocal.ThreadLocalMap threadLocals = null;}

Thread中有一个 threadLocals 属性表示线程的本地变量。这个属性的类型是 ThreadLocal.ThreadLocalMap

2. ThreadLocalMap这是什么?

ThreadLocalMapThreadLocal的内部类,他是类 Map结构,并用 Entry封装 K-V。不同的是 ThreadLocalMap的 Entry的 Key只能是 ThreadLocal类型对象,并且是一个弱引用(下面会详细详解)。
在这里插入图片描述
也就是说线程通过一个类Map数据结构ThreadLocal.ThreadLocalMap来存储属于自己的线程变量。

3. ThreadLocal详解

  • ThreadLocal 先对其进行介绍后进行测试。
  • ThreadLocalMap赋值、取值操作的入口在其外部类 ThreadLocal中。
  • 使用时我们只需要操作ThreadLocal即可。
  1. set(T )方法内调用 ThreadLocalMap 的 set(this,v)方法存值。

在这里插入图片描述2. get()方法内调用 ThreadLocalMap的 getEntry(this)方法取值

在这里插入图片描述## 4. 测试

public class TestThreadLocal {public static void main(String[] args) {ThreadLocal threadLocal = new ThreadLocal();threadLocal.set("第一次值");threadLocal.set("第二次值");System.out.println(threadLocal.get());}
}

在这里插入图片描述通过set(T)方法可知存储的是当前TheadLocal对象和值,所以新值会替换旧值

三、什么是弱引用呢?

3.1 谈谈引用关系都有哪些,区别又是什么?

  1. 强引用: 当内存不足时,JVM开始进行GC(垃圾回收),对于强引用对象,就算出现OOM(内存溢出)也不会对该对象进行回收

  2. 软引用: 当系统内存充足时,不会被回收,当系统内存不足时会被回收,内存够用就保留,不够用就回收

  3. 弱引用: 比软引用的生存周期更短,只要垃圾回收,不管JVM的内存空间是否够用,都会回收该对象占用的内存空间。

  4. 虚引用: 形同虚设,虚引用不会决定对象的生命周期(主要配合队列,在销毁前做一些操作)。

3.2 ThreadLocal为何使用弱引用

容易被GC回收,对于ThreadLocal而言,为最小化减少内存泄漏的可能性和影响,在ThreadLocal的get,set方法被调用的时候,都会清除线程map里面所有key为null的值。

3.3 内存泄漏是什么,如何避免TheadLocal的内存泄漏?

内存泄漏: 申请了内存,但是该内存一直无法释放,申请内存时,发现内存不足,就会报错OOM问题

如何避免

  • TheadLocal本身会在get,set时清除key为null的值
  • Entry对象本身为弱引用
  • 在使用完该对象时,手动调用remove方法

四、总结

  • Thread用类似 Map的 ThreadLocal.ThreadLocalMap数据结构来存储以 ThreadLocal类型的变量为 Key的数值,并用 ThreadLocal来存取删,操作 ThreadLocalMap
  • 调用 set(T)方法时,就是以当前ThreadLocal变量为 key,传入参数为 value,向 ThreadLocal.ThreadLocalMap存数据
  • 当我们调用 get()方法时,就是以当前 ThreadLocal变量为 key,从 ThreadLocal.ThreadLocalMap取对应的数据
  • 使用完后记得调用remove()方法

在这里插入图片描述在这里插入图片描述


http://www.ppmy.cn/news/105397.html

相关文章

如何使用 Megatron-LM 训练语言模型

在 PyTorch 中训练大语言模型不仅仅是写一个训练循环这么简单。我们通常需要将模型分布在多个设备上,并使用许多优化技术以实现稳定高效的训练。Hugging Face 🤗 Accelerate 的创建是为了支持跨 GPU 和 TPU 的分布式训练,并使其能够非常容易的…

Qt Quick系列(4)—定位元素

🚀作者:CAccept 🎂专栏:Qt Quick 文章目录 前言相对布局代码示例示例一示例二示例三示例四示例五示例六 简单"布局器"ColumnRowGridFlow 结语 前言 在Qt Quick中,可以使用以下方式来定位元素:…

Transformer升级之路:一种全局长度外推的新思路

©PaperWeekly 原创 作者 | 苏剑林 单位 | 追一科技 研究方向 | NLP、神经网络 说到 Transformer 无法处理超长序列的原因,大家的第一反应通常都是 Self Attention 的二次复杂度。但事实上,即便忽略算力限制,常规的 Transformer 也无法处…

女子称怀孕4个月被老公多次家暴,家可是一个人最温暖的港湾

家庭是一个人最温暖的港湾,应该是一个充满爱、和谐和尊重的地方。 近日,江西景德镇一女子发视频爆料自己怀孕4个月遭到老公家暴。视频中,男子对女子拽头发、用脚踢踹,引起了广泛关注和谴责。 据当事女子表示,这并不是第…

【Rust日报】2023-05-27 Diesel 2.1

Diesel 2.1 我很高兴宣布diesel 2.1,Diesel是一个用Rust构建的安全,可扩展的 ORM 和Query Builder。 此版本包含几个新特性并改进了现有特性。 文章链接,https://diesel.rs/news/2_1_0_release.html Github 链接,https://github.c…

多语言电商系统_国际化电商系统流程

跨境电商系统是基于计算机技术和互联网平台的一种电子商务系统。它通常包括前端电商网站或应用程序、后台管理系统、物流管理系统、支付系统等多个模块,可以通过网络实现商品展示、订单管理、支付结算、物流配送等电商流程的自动化处理。 跨境电商系统基本流程包括…

Jenkins+Gogs自动远程Docker环境部署django项目

1.Jenkins安装或确认必要插件 jenkins安装或确认必要插件gitlab、Publish Over SSH。 Dashboard--Manage Jenkins--Plugin Manager 2.Publish Over SSH配置 jenkins配置SSH连接django服务部署的对象服务器 Dashboard--Manage Jenkins--Configure System,找到 Publ…

汇编调试及学习

汇编调试 打印寄存器的值 打印内存地址 打印8字节,就是64位 打印格式 是从低位取过来的 b 字节 h 双字节 w四字节 g八字节 前变基 后变基 。 后变基这个变基会发生变化的。前变基变基不会发生变化需要用!号。 前变基 , 加了&#xff0…