当前位置: 首页 > news >正文

ThreadLocal线程局部变量

1.原理

        ThreadLocal是用来保存当前线程数据的,每一个线程的内部都有一个ThreadLocalMap,当前这个map中存储了以当前ThreadLocal,具体的数据的一个个Entry对象。

                

        为什么非得以ThreadLocal对象作键呢?因为一个线程可能使用了不止一个ThreadLocal对象,如果以当前线程对象做键,再去找对应的ThreadLocal就很麻烦,产生混淆。

        由于每一个线程都有属于自己的ThreadLocal线程局部变量,所以很好的实现了线程之间的数据隔离ThreadLocal中保存的数据仅属于当前线程)。       

2.ThreadLocal中的常见方法:

        (1)存储数据        set()

        (2)获取数据        get()

        (3)清除数据         remove()

        那么问题来了,具体是怎样利用ThreadLocalMap查找数据的呢?不论是set()、get()、remove()等方法对当前map进行操作时,最终都定位到了通过计算出的下标来操作。

        而这个下标是通过哈希算法计算得到的,操作ThreadLocalMap是以当前的ThreadLocal作key,通过当前的key的HashCode值和Entry[]数组长度-1“&”运算,来计算出实际操作位置的下标,从而达到访问元素的目的。        

        作按位与运算的效果和利用哈希值直接进行取余%运算一样,但效率大大提高

3.如何实现父子线程共享数据?

        利用了jdk提供ThreadLocal的子类InheritableThreadLocal来实现。

public class ThreadLocalTest {public static void main(String[] args) {InheritableThreadLocal<String> threadLocal = new InheritableThreadLocal<String>();threadLocal.set("风萧萧兮易水寒");System.out.println("main主线程:"+threadLocal.get());Thread thread = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("子线程:"+threadLocal.get());}});thread.start();}
}

        main函数为父线程,创建了一个thread子线程,利用InheritableThreadLocal这个子类来共享父线程的数据。

        父线程子线程均输出“风萧萧兮易水寒”。

4.ThreadLocal如何避免内存泄露

        执行完相关的业务逻辑后,最终在finally代码块中都会调用remove()方法,将当前map中的ThreadLocal键置为空,value置为空,从而在垃圾回收的时候及时回收无用数据。

5.应用

        (1) 线程的数据隔离

        因为ThreadLocal对象只属于当前线程,那么ThreadLocal中的数据也属于当前线程,在多线程并发的情况下,很好的实现了不同线程的数据隔离,避免了采用synchronized锁机制来保证线程安全而导致的性能上的代价。

        例如:SqlSession会话对象绑定,避免多个线程使用同一个SqlSession对象,由于关闭导致异常。

//当前线程的线程局部变量
private static final ThreadLocal threadSession= new ThreadLocal();public static SqlSession getSession(){//获取session会话方法SqlSession s = (SqlSession)threadSession.get();//通过仅属于当前线程的threadSession对象来获取if(s==null){//为空s = getSqlSessionFactory().openSqlSession();//则重新建立会话threadSession.set(s);//并存到ThreadLocalMap中去}
}

        (2)跨函数调用

        数据通常用于同一个类中的传递,如果利用方法传递势必要关心方法的返回值类型及参数,但利用ThreadLocal可以直接实现获取,这样做还达到了解耦的效果。

        例如:RequestContextHolder源码就有很好的体现

@Nullable  
public static RequestAttributes getRequestAttributes() {// 获取当前线程中的存储的Request Attribute//直接通过ThreadLocal对象来获取RequestAttributes attributes = requestAttributesHolder.get();  if (attributes == null) {  attributes = inheritableRequestAttributesHolder.get();  }  return attributes;  
}private static final ThreadLocal<RequestAttributes> requestAttributesHolder =  new NamedThreadLocal<>("Request attributes");  private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder =  new NamedInheritableThreadLocal<>("Request context");

以上就是我对ThreadLocal线程区域对象的粗略理解,欢迎诸君共同探讨。

相关文章:

ThreadLocal线程局部变量

1.原理 ThreadLocal是用来保存当前线程数据的&#xff0c;每一个线程的内部都有一个ThreadLocalMap&#xff0c;当前这个map中存储了以当前ThreadLocal作键&#xff0c;具体的数据作值的一个个Entry对象。 为什么非得以ThreadLocal对象作键呢&#xff1f;因为一个线程可能使用了…...

C++ Primer (第五版)第一章习题部分答案

在我自学C过程中&#xff0c;我选择了CPrimer这本书&#xff0c;并对部分代码习题进行了求解以及运行结果。接下来几个月我将为大家定时按章节更新习题答案与运行结果: 目录 1.9编写程序,使用while循环将50到100的整数相加 1.10 除了运算符将运算对象的值增加1之外,还有一个…...

Python与GUI集成:零基础也能开发国际象棋游戏

引言&#xff1a; 国际象棋&#xff0c;作为世界上最受欢迎的棋类游戏之一&#xff0c;拥有丰富的策略和深度。但是&#xff0c;你知道自己可以使用Python来创建一个简单的国际象棋游戏并为其添加图形用户界面&#xff08;GUI&#xff09;吗&#xff1f;在本教程中&#xff0c…...

SaaS软件能保证数据安全吗?

SaaS软件能保证数据安全吗&#xff1f; 本文将要尝试从各个方面尽可能客观的去阐述这个问题&#xff0c;而不是简单自嗨式的说简道云平台如何保障数据安全。 建议先收藏起来慢慢品&#xff01; 01 SaaS安全到底是什么&#xff1f;——定义解读 本文所用SaaS平台>>>…...

方案:基于AI烟火识别与视频技术的秸秆焚烧智能化监控预警方案

一、方案背景 为严控秸秆露天焚烧&#xff0c;改善环境空气质量&#xff0c;各省相继发布秸秆禁烧工作内容。以安徽省为例&#xff0c;大气污染防治联席会议下发了该省2020年秸秆禁烧工作部署通知。2020年起&#xff0c;气象局将对全省秸秆焚烧火点实施卫星全年全时段监测&…...

phantomjs插件---实现通过链接生成网页截图

Phantomjs | PhantomJS 配置要求 windows下&#xff0c;安装完成phantomJS 设置phantomjs环境变量【也可直接使用phantomjs目录下的执行文件】 直接通过访问php文件执行/通过cmd命令行执行【phantomjs phantom_script.js】 linux下,安装完成phantomJS 设置phantomjs环境变量 直…...

SpringBoot分页实现查询数据

1.原生查询 1.1创建分页查询实体类 package com.itheima.pojo;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.util.List;//分页查询结果封装类 Data NoArgsConstructor AllArgsConstructor public class PageBean {pr…...

Jetson Xavier NX 与飞控(Pixhawk 4 Mini)实现串口通信

一、飞控端配置 首先对 Pixhawk 4 Mini 烧录固件参考 Kakute H7 刷写 px4 固件_想要个小姑娘的博客-CSDN博客 烧录完成后打开 QGroundControl&#xff0c;进入参数设置并搜索 MAV&#xff0c;如下所示 然后修改 MAV_1_CONFIG&#xff0c;修改为自己想要连接机载电脑&#xf…...

为什么2022年秋招嵌入式开发岗位薪资大涨?

今天看到一个网友讨论的问题&#xff0c;其实这个问题也很简答。从嵌入式本身优势来说&#xff0c;首先是因为该行业人才人才需求大&#xff0c;据权威统计机构统计在所有软件开发类人才的需求中&#xff0c;对嵌入式工程师的需求达到全部需求量的60%~80%&#xff0c;并且每年以…...

在HTML里,attribute和property有什么区别?

在HTML中&#xff0c;attribute 和 property 之间的区别是一个常见但容易混淆的概念。它们都与HTML元素有关&#xff0c;但它们在功能、用途和行为上有所不同。以下是它们之间的主要区别&#xff1a; 定义和来源: Attribute: 它们是在HTML标记中定义的&#xff0c;通常用于提供…...

机器学习入门与实践:从原理到代码

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 在本文中&#xff0c;我…...

SpringCloud在idea中一键启动项目

1、如下图文件中加上&#xff1a; <component name"RunDashboard"><option name"configurationTypes"><set><option value"SpringBootApplicationConfigurationType" /></set></option></component>…...

VB过程的递归调用,辗转相除法求最大公约数

VB过程的递归调用&#xff0c;辗转相除法求最大公约数 过程的递归调用&#xff0c;辗转相除法求最大公约数 Private Function gys(ByVal m%, ByVal n%) As IntegerDim r%r m Mod n m大或者n大都无所谓&#xff0c;这个不影响计算&#xff0c;由于辗转相除法的算法&#xff0c…...

OpenCV(三十九):积分图像

1.积分图像介绍 积分图像中的每个像素表示了原始图像中对应位置及其左上方矩形区域内像素值的总和。如图&#xff0c;p0表示原始图像蓝色区域内像素值的总和。 倾斜求和&#xff08;Skewed Sum&#xff09;是积分图像的一种扩展形式&#xff0c;用于计算图像区域内的像素和&…...

【Electron 拦截请求实现自定义网络处理】

文章目录 Electron 拦截请求实现自定义网络处理1. 获取默认会话2. 拦截请求3. 完整示例代码总结 Electron 拦截请求实现自定义网络处理 在 Electron 中&#xff0c;我们可以使用 session 模块来拦截和处理网络请求。通过拦截请求&#xff0c;我们可以对请求进行修改、添加请求…...

Pytest系列-内置标签skip和skipif 跳过测试用例的详细使用(5)

简介 skip和skipif&#xff0c;见名知意就是跳过测试&#xff0c;主要用于不想执行的代码&#xff0c;标记后&#xff0c;标记的代码不执行。希望满足某些条件才执行某些测试用例&#xff0c;否则pytest会跳过运行该测试用例实际常见场景&#xff1a;根据平台不同执行测试、跳…...

华为云云耀云服务器L实例评测|docker 常用操作命令

文章目录 写在前面云耀云服务器L实例与ECS的购买和配置区别 1、管理命令2、帮助命令3、镜像命令4、容器命令4.1 查看容器4.2 创建容器 实例 写在前面 ​ 前面讲到了docker环境的安装&#xff0c;这是我们可以直接打开远程连接华为云云耀云服务器L实例&#xff0c;直接连接公网…...

RJ45网络信号浪涌保护器解决方案

RJ45网络信号浪涌保护器是一种用于保护网络设备免受雷击或其他高压电流干扰的装置&#xff0c;它可以有效地吸收和释放信号线路上的过电压&#xff0c;从而避免设备损坏或数据丢失。 RJ45信号浪涌保护器的应用领域和施工方案如下&#xff1a; 地凯科技RJ45网络信号浪涌保护器…...

SoC性能指标ARM内核运算能力

自动驾驶芯片常用的性能评价指标:TOPS,DMIPS,GFLOPS分别说的是啥&#xff1f; TOPS Tera Operation Per Second&#xff0c;表示每秒钟可以进行的操作数量&#xff0c;用于衡量自动驾驶的算力。 众所周知&#xff0c;汽车上最常用的传感器是摄像头&#xff0c;而与之对应的计…...

注册小鲸鱼88888专用网站

点击注册充值即可 高效不限速&#xff0c;不限设备 注意这里的地址并没有错&#xff0c;只是你需要想办法正确能进入就行&#xff0c;懂的大佬一定知道用一定的方法访问的。...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...