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 输出:[“((()))”,“(()())…

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

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

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普通文件目录文件软链接文件块设备文件,也就是硬盘等存储设备的文件字符设备文件,是鼠…

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

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

代码随想录算法训练营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),饱和度(Saturation)和明度(Value), 原本输出的HSV 的取值范围分别是0-360, 0-1, 0-1; 但是为了匹配目标数据类型OpenCV 将每个通道的取值范围都做了修改,于是就变成了0-180, 0-255, 0-255 impo…

RabbitMQ保证消息的可靠性

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

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多变量时间…

云原生概念

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

【已解决】引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。

这种问题产生一般都会手足无措,包括笔者,但是不要慌,这种问题一般都是内存泄漏引起的。例如读者要访问一个已经被析构或者释放的变量,当然访问不了,导致存在问题。这时候读者应该从哪里产生内存泄漏这方面进行考虑&…

【VSCode】设置 一键生成vue模板 的快捷入口

问题 每次写一个组件的时候,都需要去手敲默认结构或者是复制粘贴,十分的麻烦! 解决办法 文件 > 首选项 > 用户代码片段 > vue.json 配置vue模板 其中prefix是用来触发代码段的内容,即模版的快捷入口;body里…

【Funny Game】 吃豆人

目录 【Funny Game】 吃豆人 吃豆人 文章所属专区 Funny Game 吃豆人 吃豆人,这款经典游戏如今依旧魅力四射。玩家需操控小精灵,在迷宫内吞噬所有豆子,同时避开狡猾的鬼怪。当吃完所有豆子后,便可消灭鬼怪,赢得胜利。…

springboot197基于springboot的毕业设计系统的开发

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的毕业设计系统的开发 适用于计算机类毕业设计,课程设计参考与学习用途。仅供学习参考, 不得用于商业或者非法用途,否则,一切后果请用户自负。 看运行截图看 第五章 第四章 …

[AIGC] 利用 ChatGpt 深入理解 Java 虚拟机(JVM)的内存分布

深入理解 Java 虚拟机(JVM)的内存分布 Java 虚拟机(JVM)是 Java 编程语言的核心运行环境,它负责解释和执行 Java 字节码。在 JVM 中,内存被划分为几个不同的区域,每个区域都有特定的用途。了解…

c++作业

Shell中的函数(先调用后使用的原则)(没有申明) (Function) 函数名(有没有参数根据调用格式)(不能写任何内容) { 函数体 Return 返回值 } 函数名 ----》…

Go语言中的加密艺术:深入解析crypto/subtle库

Go语言中的加密艺术:深入解析crypto/subtle库 引言crypto/subtle库概览ConstantTimeCompare函数深入解析ConstantTimeSelect函数应用详解ConstantTimeLessOrEq函数实践指南安全编程实践性能优化与最佳实践与其他加密库的比较总结 引言 在当今快速发展的互联网时代&…