ThreadLocal “你”真的了解吗?

今天想梳理一个常见的面试题。在开始之前,让我们一起来回顾一下昨天的那篇文章——《Spring 事务原理总结七》。这篇文章比较啰嗦,层次也不太清晰,所以以后有机会我一定要重新整理一番。这篇文章主要想表达这样一个观点:Spring的嵌套事务是通过ThreadLocal实现的。当一个请求从浏览器发送到后台以后,后台会启动一个线程去处理这个请求,在处理的过程中如果用到了一个需要事务的方法A,而A又调用了另一个需要事务的方法B,那么这时就发生了事务嵌套(同时还涉及到了事务传播行为,即事务A与事务B之间的相互关系)。为了解决事务嵌套的问题,Spring又定义了一个记录与事务相关的信息的类TransactionInfo。这样A就有了一个对应的TransactionInfo对象,B也有了一个对应的TransactionInfo对象。而A调用了B,所以A和B对应的TransactionInfo对象之间就有了关联关系。在TransactionInfo类中有一个oldTransactionInfo属性,这个记录的就是老的事务对象。看过前面系列文章又好好思考过的童鞋可能已经明白了,在A中通过代理调用B的时候,此时两个事务位于同一线程中,接着将A对应的TransactionInfo对象赋值给B对应的TransactionInfo对象的oldTransactionInfo属性,然后将B对应的TransactionInfo对象绑定到ThreadLocal,接着待B执行完后,将当前线程绑定的TransactionInfo还原为A对应的TransactionInfo,此时就完成了嵌套事务之间信息传递。具体参见下面这幅图:

 上面这幅图并不完美,但将前面一段的描述图形化,这应该会好理解一点吧!在这段回顾中,我们不断提到ThreadLocal,那它究竟是干什么的?原理又是什么呢?想必大家也都听说过,ThreadLocal存在内存泄漏的风险,这又是咋回事呢?

概述

ThreadLocal,即线程本地变量,是Java中用于提供线程局部存储的类,位于java.lang包下它的核心原理在于为每个使用ThreadLocal的线程创建一个独立的副本,使得每个线程在访问ThreadLocal时获取到的是自己线程内的私有数据,而不是共享同一份数据,从而避免了多线程间的同步问题。其工作机制是这样的:

  • 内部存储结构:ThreadLocal内部维护了一个Map数据结构,其键是当前的线程对象(ThreadLocal.ThreadLocalMap),值是我们想要隔离存储的对象实例这意味着每个线程都有一个独立的ThreadLocalMap来保存自己的ThreadLocal副本
  • 存取操作:
  1. set(T value)方法允许我们设置线程局部变量的值。它会将给定的值与当前执行线程关联起来,在该线程的ThreadLocalMap中存储
  2. get()方法则返回当前线程所对应的ThreadLocal变量的副本值。如果该线程尚未初始化,则可能返回默认值或抛出异常
  3. remove():移除线程本地变量。注意在线程池的线程复用场景中在线程执行完毕时一定要调用remove,避免在线程被重新放入线程池中时被本地变量的旧状态仍然被保存。
  • 线程生命周期管理:当线程结束生命周期后,其内部的ThreadLocalMap应该被清理以释放资源然而,如果线程不再使用某个ThreadLocal但未手动删除引用,可能会导致内存泄漏,因为ThreadLocalMap中的Entry不会自动移除
  • 弱引用与内存泄漏:在内部实现上,ThreadLocalMap的条目是通过弱引用(WeakReference)指向ThreadLocal实例的,这意味着只有当没有强引用指向ThreadLocal实例时,这些条目才能被垃圾回收器回收。但如果仅ThreadLocalMap中的条目持有目标对象的唯一引用,即使线程已经完成任务,由于弱引用的存在,目标对象也不会立即被回收,这可能导致无用对象占据内存空间,直到下次JVM进行垃圾回收周期时才可能清除。
  • 使用场景:ThreadLocal常用于需要在线程间隔离状态信息的情况,例如数据库连接、事务上下文、用户身份信息等,尤其是在处理每个线程都需要独立的实例且不希望影响其他线程的情况下。

总的来说,ThreadLocal通过为每个线程维护一份独立的数据副本,巧妙地实现了多线程环境下的数据隔离和安全性,并简化了代码的编写,减少了同步块或锁的使用。但它也要求开发者关注并正确管理其生命周期,以免引发内存泄露问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/690466.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot+Vue的零食零售管理系统

末尾获取源码作者介绍:大家好,我是墨韵,本人4年开发经验,专注定制项目开发 更多项目:CSDN主页YAML墨韵 学如逆水行舟,不进则退。学习如赶路,不能慢一步。 目录 一、项目简介 二、开发技术与环…

Rocky Linux 下载安装

一、VMware Workstation下载安装 1、安装教程 VMware Workstation下载安装(含密钥) 二、VMware Workstation 创建虚拟机 1、创建教程 VMware Workstation 创建虚拟机 三、Rocky Linux 下载 1、下载官网 RockyLinux.org 2、选择X86架构_64位系统_DVD镜…

部分回溯法题解

部分回溯法题解 一、22. 括号生成二、39. 组合总和 一、22. 括号生成 中 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 示例 1: 输入:n 3 输出:[“((()))”,“(()())…

javascript 中的class 和typescript中的class的区别

JavaScript 中的类(class)和 TypeScript 中的类有一些相似之处,但 TypeScript 在其类的定义和使用方面引入了一些额外的功能和语法糖,以提供更严格的类型检查和更丰富的面向对象编程功能。下面是一些主要的区别: 类型注…

【第61例】市场管理MM流程:定价策略

目录 1. 内容简介 2. 为什么要做定价? 3. 一些主流的定价策略 作者简介 1. 内容简介 在之前的内容&#

1.网络游戏逆向分析与漏洞攻防-游戏启动流程漏洞-测试需求与需求拆解

内容参考于:易道云信息技术研究院VIP课 上一个内容:分析接收到的对话数据包 这是一个新的篇章,之前是关于把我们的东西放进游戏里和内存里的数据分析与利用,现在是专注于网络部分,通过分析网络数据包得到应用程序中各…

什么是MVVM?MVC、MVP与MVVM模式的区别?

MVVM(Model-View-ViewModel)是一种软件架构模式,用于将用户界面(View)与业务逻辑(Model)分离,并通过ViewModel来连接两者。MVVM的目标是实现可测试性、可维护性和可复用性。 MVC&am…

Python安装GDAL库

目录 一、GDAL介绍 二、GDAL应用 三、python安装GDAL库 一、GDAL介绍 GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式,并且提供了一系列命令…

基于Spring Boot的智能物流管理系统,计算机毕业设计(带源码+论文)

源码获取地址: 码呢-一个专注于技术分享的博客平台一个专注于技术分享的博客平台,大家以共同学习,乐于分享,拥抱开源的价值观进行学习交流http://www.xmbiao.cn/resource-details/1759581137025445890

linux基础学习(10):基本权限与相关命令

1.基本权限 用ls -l查看当前目录文件时,可以看到文件的基本权限 其由10位组成,其中: 第1位:代表文件类型。 - d lbc普通文件目录文件软链接文件块设备文件,也就是硬盘等存储设备的文件字符设备文件,是鼠…

详解MySQL增删查改

众所周知&#xff0c;MySQL是非常重要的数据库语言&#xff0c;下面我们来回顾一下mysql的增删查改吧 MySQL创建数据库&#xff1a; CREATE DATABASE 数据库名;MySQL删除数据库&#xff1a; DROP DATABASE <database_name>; --直接删除&#xff0c;不检查是否存在 DROP…

外包干了3个多月,技术退步明显。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入广州某软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

【LUA】时间面板显示

最近看了个HS的时间显示的例子&#xff0c;顺便学习了一下这个lua定义函数的方法&#xff0c;被折腾了许久&#xff0c;最后竟然是gpt解答了。 定义方式 -- 定义一个对象 local myObject {isVisible false, }-- 定义对象的方法 function myObject:toggleShow()self.isVisibl…

代码随想录算法训练营29期|day54 任务以及具体安排

第九章 动态规划part11 123.买卖股票的最佳时机III // 版本一 class Solution {public int maxProfit(int[] prices) {int len prices.length;// 边界判断, 题目中 length > 1, 所以可省去if (prices.length 0) return 0;/** 定义 5 种状态:* 0: 没有操作, 1: 第一次买入…

OpenCV中图像的HSV色彩空间

在HSV 色彩空间中H, S, V 这三个通道分别代表着色相(Hue)&#xff0c;饱和度(Saturation)和明度(Value)&#xff0c; 原本输出的HSV 的取值范围分别是0-360, 0-1, 0-1; 但是为了匹配目标数据类型OpenCV 将每个通道的取值范围都做了修改,于是就变成了0-180, 0-255, 0-255 impo…

RabbitMQ保证消息的可靠性

1. 问题引入 消息从发送&#xff0c;到消费者接收&#xff0c;会经理多个过程&#xff1a; 其中的每一步都可能导致消息丢失&#xff0c;常见的丢失原因包括&#xff1a; 发送时丢失&#xff1a; 生产者发送的消息未送达exchange消息到达exchange后未到达queue MQ宕机&…

Leetcode 21-25题

合并两个有序链表 将两个升序链表合并为一个新的升序链表。 用两个指针指向两个链表的表头&#xff0c;然后每次比较一下哪个值小&#xff0c;将较小的节点接到答案后面即可。 ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {auto dummy new ListNode(), p du…

EI级 | Matlab实现TCN-GRU-MATT、TCN-GRU、TCN、GRU多变量时间序列预测对比

EI级 | Matlab实现TCN-GRU-MATT、TCN-GRU、TCN、GRU多变量时间序列预测对比 目录 EI级 | Matlab实现TCN-GRU-MATT、TCN-GRU、TCN、GRU多变量时间序列预测对比预测效果基本介绍程序设计参考资料 预测效果 基本介绍 【EI级】Matlab实现TCN-GRU-MATT、TCN-GRU、TCN、GRU多变量时间…

云原生概念

云原生是一条使用户能&#xff1a; 1.低运维、 2.敏捷的、 3.以可扩展、可复制的方式&#xff0c; 最大化的利用”云“的能力、发挥”云“的价值的最 佳路径 云原生&#xff0c;是一条最佳路径或实践 参考&#xff1a;https://edu.aliyun.com/course/314164/lesson/7815

JavaScript 中实现常见数据结构:栈、队列与树

文章目录 JavaScript 中实现常见数据结构&#xff1a;栈、队列与树引言一、栈&#xff08;Stack&#xff09;二、队列&#xff08;Queue&#xff09;三、树&#xff08;Tree&#xff09;结语与祝福代码 JavaScript 中实现常见数据结构&#xff1a;栈、队列与树 引言 在前端开…