ThreadLocal的用法

概述

ThreadLocal提供了线程局部变量,用于在线程中保存数据,在ThreadLocal中保存的数据仅属于当前线程,所以ThreadLocal实例的get或set方法访问自己的独立副本,这些副本之间相互隔离,互不影响

ThreadLocal利用Thread中维护的ThreadLocalMap来保存数据

实例:


public class ThreadLocal_Test01 {private static ThreadLocal<String> nameLocal=new ThreadLocal<String>();private static ThreadLocal<String> idLocal=new ThreadLocal<String>();public static void main(String[] args) {Thread t1=new Thread(()->{try {//保存数据nameLocal.set("鹭卓");idLocal.set("001");//调用方法,重新获取数据dosth();}finally {nameLocal.remove();idLocal.remove();}},"线程1");Thread t2=new Thread(()->{try {//保存数据nameLocal.set("卓沅");idLocal.set("008");//调用方法,重新获取数据dosth();} finally {nameLocal.remove();idLocal.remove();}},"线程2");t1.start();t2.start();}public static void dosth() {//通过ThreadLocal,获取当前线程中的数据String name=nameLocal.get();System.out.println(Thread.currentThread().getName()+"-->dosth():"+name);String id=idLocal.get();System.out.println(Thread.currentThread().getName()+"-->dosth():"+id);//线程继续调用方法,获取当前线程中的数据show();}public static void show() {//通过ThreadLocal,获取当前线程中的数据String name=nameLocal.get();System.out.println(Thread.currentThread().getName()+"-->show():"+name);String id=idLocal.get();System.out.println(Thread.currentThread().getName()+"-->show():"+id);}
}

运行结果:

ThreadLocal常用方法

1、存储数据至当前线程的ThreadLocalMap:public void set(T value);

2、从当前线程的ThreadLocalMap中获取数据:public T get();

3、从当前线程的ThreadLocalMap中删除数据:public void remove();

ThreadLocalMap内部结构

ThreadLocalMap内部数据结构是一个Entry类型的数组,每个Entry对象的key为ThreadLocal对象,value为存储的数据

为什么使用ThreadLocal做key?

如果应用中,一个线程中只使用一个ThreadLocal对象,那么使用Thread做key可以,代表每一个Thread线程对应一个value

如果一个线程中不只使用了一个ThreadLocal对象,这时就不能用Thread做key,因为key值是唯一的

父子线程如何共享数据?

使用ThreadLocal是不行的,main方法在主线程中执行的,相当于父线程,在main方法中开启另一个线程相当于子线程,两个线程对象拥有不同的ThreadLocalMap,不能共享数据

例子

//父子线程传递数据
public class ThreadLocal_Test02 {public static void main(String[] args) {ThreadLocal<String> local=new ThreadLocal<String>();local.set("天王盖地虎");System.out.println("主线程:"+local.get());//创建子线程Thread t=new Thread(()->{System.out.println("子线程:"+local.get());});t.start();}
}

运行结果:

使用InheritableThreadLocal,它是JDK自带的类,继承自ThreadLocal类

例子:


//父子线程传递数据
public class ThreadLocal_Test02 {public static void main(String[] args) {//		ThreadLocal<String> local=new ThreadLocal<String>();//允许子线程与父线程共享数据InheritableThreadLocal<String> local=new InheritableThreadLocal<String>();local.set("天王盖地虎");System.out.println("主线程:"+local.get());//创建子线程Thread t=new Thread(()->{System.out.println("子线程:"+local.get());});t.start();}
}

运行结果:

ThreadLocal如何避免内存泄露?

在使用完ThreadLocal对象后,在finally中调用ThreadLocal对象的remove()方法

remove()方法中会把Entry中的key和value都设置成null,这样就能被GC及时回收,无需触发额外的清理机制,所以能解决内存泄漏问题

ThreadLocal应用场景

  • 多线程环境下的资源隔离:在多线程应用中,每个线程可能需要独立的变量副本,如数据库连接、用户会话信息等。使用ThreadLocal可以避免多个线程之间对这些资源的共享冲突。例如,在一个 Web 应用中,每个用户请求可能由一个单独的线程处理,使用ThreadLocal可以为每个线程存储独立的用户会话相关的变量,如用户 ID、权限等。

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

  • 线程上下文信息传递ThreadLocal可以用于在同一个线程的不同方法之间传递信息,而不需要显式地在方法参数中传递这些信息。例如,在一个复杂的业务逻辑处理过程中,多个方法可能都需要访问当前线程相关的一些上下文信息,如事务 ID 等,可以使用ThreadLocal来存储和传递这些信息。

例如spring中存储的request请求信息

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

YOLOv8改进系列,YOLOv8替换主干网络为PP-HGNetV2(百度飞桨视觉团队自研,助力涨点)

摘要 PP-HGNetV2(High Performance GPU Network V2) 是百度飞桨视觉团队自研的 PP-HGNet 的下一代版本,其在 PP-HGNet 的基础上,做了进一步优化和改进,最终在 NVIDIA GPU 设备上,将 “Accuracy-Latency Balance” 做到了极致,精度大幅超过了其他同样推理速度的模型。其在…

828华为云征文|基于华为云Flexus X实例快速搭建Halo博客平台

目录 前言 一、Flexus云服务器X介绍 1.1 Flexus云服务器X实例简介 1.2 Flexus云服务器X实例特点 1.3 Flexus云服务器X实例场景需求 二、Flexus云服务器X购买 2.1 Flexus X实例购买 2.2 购买MySQL加速镜像 2.3 重置密码 2.4 登录服务器 三、Flexus X实例安装Docker 3.1 系统版本…

天宝Trimble RealWorks2024.0.2注册机 点云后处理软件 点云三维重建软件

一、功能特色 1、强大的点云数据处理平台 Trimble Realworks2024是市面上先进的点云数据处理软件&#xff0c;能够配准、可视化、浏览和直接处理市面上几乎所有主流品牌扫描仪点云数据&#xff0c;包括Leica、Riegl、ZF、Faro、Topcon等。 2、业界领先的无目标全自动配准 T…

前端大数据渲染:虚拟列表、触底加载与分堆渲染方案

前言 针对表格展示数据&#xff0c;用户提出要求前端在表格下面有一展示多少条数据的选项&#xff0c;如果要求一次性展示10000条数据&#xff0c;如果直接染会造成页面的卡顿&#xff0c;渲染速度下降&#xff0c;内容展示慢,如果有操作&#xff0c;操作会卡顿 下面总结常见…

【C++】STL----list常见用法

&#x1f525;个人主页&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收录专栏&#x1f308;&#xff1a;C从小白到高手 &#x1f339;往期回顾&#x1f339;&#xff1a;[C]vector常见用法 &#x1f516; 流水不争&#xff0c;争的是滔滔不息。 文章目录 一、list的介绍li…

【软件基础知识】什么是 API,详细解读

想象一下,你正在使用智能手机上的天气应用。你打开应用,瞬间就能看到实时天气、未来预报,甚至是空气质量指数。但你有没有想过,这些数据是如何神奇地出现在你的屏幕上的?答案就在三个字母中:API。 API,全称Application Programming Interface(应用程序编程接口),是现代软件世…

数字签名和CA数字证书的核心原理

看了蛋老师的视频就很容易理解了&#xff0c;首先对服务器的公钥和信息进行哈希运算得到一个短字符串&#xff0c;然后用CA机构中的私钥对这一短字符串进行加密就得到了一个数字签名&#xff0c;然后就这个数字签名放到数字证书中&#xff0c;同时服务器的公钥也放在数字证书中…

Unity之FPS

目录 &#x1f3ae;MouseLook摄像机旋转脚本 &#x1f3ae;PickUpItem武器拾取脚本 &#x1f3ae;PlayerController玩家控制器 &#x1f3ae;Inventory武器库 &#x1f3ae;Weapon武器抽象类 &#x1f3ae;Weapon_AutomaticGun武器脚本 其实这个教程很早就收藏了就是被20…

9.20哈好

函数体 #include"SeqList.h"void SeqList::init(int n) {this->ptrnew data[n];this->len0;this->sizen; }bool SeqList::empty() {return this->len0; }bool SeqList::full() {return this->sizethis->len; }void SeqList::push_back(data e) {i…

未来通信抢先看!遨游通讯2024年中国国际信息通信展亮点剧透

2024年中国国际信息通信展览会将于9月25日-27日在北京国家会议中心举行&#xff0c;本届展会以“推动数实深度融合&#xff0c;共筑新质生产力”为主题。在通信技术日新月异的今天&#xff0c;卫星通信、人工智能、低碳节能等技术理念正引领着通信行业迈向新的高度。遨游通讯作…

计算机毕业设计 基于Python的汽车销售管理系统 Python+Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

string类的模拟实现以及oj题

前言 上篇博客实现了string类的begin()、end()、构造函数、析构函数、c_str、size()、clear()、capacity()、[ ]、reserve()、push_back、append()、insert()、。这篇博客实现剩下的一些重要功能。 string类的模拟实现 string.h #include<iostream> #include<stri…

(c++)线程的创建、互斥锁的使用、线程数组

1.创建10个线程&#xff0c;每个线程都做10万次全局变量num1操作&#xff0c;然后输出这个全局变量&#xff0c;预想结果应该是100万。但是线程可能在cpu分配的一个时间片中做不完10万次1的操作&#xff0c;这时候cpu会被其他线程抢占&#xff0c;由于num1不是一个原子操作&…

每日OJ题_牛客_WY22 Fibonacci数列(斐波那契)

目录 牛客_WY22 Fibonacci数列&#xff08;斐波那契&#xff09; 解析代码 牛客_WY22 Fibonacci数列&#xff08;斐波那契&#xff09; Fibonacci数列_牛客题霸_牛客网 解析代码 求斐波那契数列的过程中&#xff0c;判断⼀下&#xff1a;何时 n 会在两个 fib 数之间。 #in…

vulnhub(11):derpnstink(hydra爆破用户名和密码、验证的文件上传)

端口 nmap主机发现 nmap -sn 192.168.159.120/24 ​ Nmap scan report for 192.168.159.120 Host is up (0.00020s latency). ​ 120是新出现的机器&#xff0c;他就是靶机 nmap端口扫描 nmap -Pn 192.168.159.120 -p- --min-rate 10000 -oA nmap/scan 扫描开放端口保存到 nma…

2024.9.20营养小题【2】(动态分配二维数组)

这道题里边涉及到了动态分配二维数组的知识点&#xff0c;不刷这道题我也不知道这个知识点&#xff0c;算是一个比较进阶一点的知识点了。 参考&#xff1a;C语言程序设计_动态分配二维数组_哔哩哔哩_bilibili【C/C 数据结构 】二维数组结构解析 - 知乎 (zhihu.com)

数据结构—(java)反射,枚举,lambda表达式

文章目录 反射反射的定义&#xff1a;反射相关的类&#xff1a;反射相关的方法&#xff1a;反射示例&#xff1a;获取Class类对象创建指定类的对象反射私有属性&#xff1a;反射私有方法&#xff1a;反射私有的构造方法 枚举枚举的意义枚举类的实现枚举类的使用&#xff1a;Enu…

机器学习算法与实践_03概率论与贝叶斯算法笔记

1、概率论基础知识介绍 人工智能项目本质上是一个统计学项目&#xff0c;是通过对 样本 的分析&#xff0c;来评估/估计 总体 的情况&#xff0c;与数学知识相关联 高等数学 ——> 模型优化 概率论与数理统计 ——> 建模思想 线性代数 ——> 高性能计算 在机器学…

MySQL篇(窗口函数/公用表达式(CTE))(持续更新迭代)

目录 讲解一&#xff1a;窗口函数 一、简介 二、常见操作 1. sumgroup by常规的聚合函数操作 2. sum窗口函数的聚合操作 三、基本语法 1. Function(arg1,..., argn) 1.1. 聚合函数 sum函数&#xff1a;求和 min函数 &#xff1a;最小值 1.2. 排序函数 1.3. 跨行函数…

2024年港澳台华侨生联考分数线继续更新来啦

导读 在最近的一系列分享中&#xff0c;我们和大家一同分享了2024年港澳台华侨生联考的分数线。今天我们继续和大家一起分享一些2024年港澳台联考的高校录取分数线吧&#xff01; 首都师范大学 首都师范大学和首都医科大学作为被低估的两所高校&#xff0c;这两年的分数线也是…