ThreadLocal基本介绍
文章目录
- 什么是ThreadLocal
- ThreadLocal解决了什么问题
- ThreadLocal的作用
- ThreadLocal的使用场景
- ThreadLocal的代码示例
- ThreadLocal的优点
- ThreadLocal的缺点
- 与volatile、synchronized、ThreadLocal比较
- 总结
什么是ThreadLocal
ThreadLocal是Java中的一个线程本地变量,它提供了一种在多线程环境下保持变量的副本,每个线程都可以独立地修改自己的副本,而不会影响其他线程的副本。
ThreadLocal解决了什么问题
在多线程环境下,共享变量的访问可能会引发线程安全问题。例如,多个线程同时访问同一个变量时,可能会导致数据的不一致性和竞态条件。ThreadLocal提供了一种解决方案,通过为每个线程提供独立的副本,避免了共享变量的竞争和同步问题,从而解决了线程安全问题。
ThreadLocal的作用
ThreadLocal是解决线程安全问题一个很好的思路,它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。在很多情况下,ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。
作者:安仔夏天勤奋
链接:https://www.jianshu.com/p/6fc3bba12f38
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
ThreadLocal的使用场景
ThreadLocal适用于以下场景:
数据库连接管理:每个线程需要独立的数据库连接,可以使用ThreadLocal来管理每个线程的连接。
用户身份认证:每个线程需要独立的用户身份信息,可以使用ThreadLocal来存储用户的身份信息。
线程上下文传递:多个方法之间需要共享一些上下文信息,可以使用ThreadLocal来传递上下文信息。
ThreadLocal的代码示例
下面是一个使用ThreadLocal的简单示例,用于存储用户的身份信息:
public class UserContext {private static final ThreadLocal<User> userThreadLocal = new ThreadLocal<>();public static void setUser(User user) {userThreadLocal.set(user);}public static User getUser() {return userThreadLocal.get();}public static void clearUser() {userThreadLocal.remove();}
}public class User {private String name;// ... 其他属性和方法
}public class Main {public static void main(String[] args) {User user1 = new User("Alice");User user2 = new User("Bob");UserContext.setUser(user1);System.out.println(UserContext.getUser().getName()); // 输出:AliceUserContext.setUser(user2);System.out.println(UserContext.getUser().getName()); // 输出:BobUserContext.clearUser();System.out.println(UserContext.getUser()); // 输出:null}
}
在上面的示例中,UserContext类使用ThreadLocal来存储用户的身份信息。通过调用setUser方法来设置当前线程的用户信息,调用getUser方法来获取当前线程的用户信息,调用clearUser方法来清除当前线程的用户信息。
ThreadLocal的优点
线程隔离:每个线程都有自己独立的变量副本,不会受其他线程的影响,实现了线程间的隔离。
简单易用:使用ThreadLocal非常简单,只需要创建一个ThreadLocal对象,并调用其get和set方法即可。
高效性:ThreadLocal使用了线程的ThreadLocalMap来存储变量副本,访问速度快。
ThreadLocal的缺点
内存泄漏:如果ThreadLocal变量没有及时清理,可能会导致内存泄漏。因为ThreadLocalMap中的Entry会持有ThreadLocal对象的强引用,如果ThreadLocal对象没有被及时回收,就会造成内存泄漏。
线程间数据共享困难:ThreadLocal只能在当前线程内共享数据,在线程间传递数据相对困难,需要借助其他方式(如参数传递)来实现。
与volatile、synchronized、ThreadLocal比较

在简单变量读写场景中,使用volatile关键字可以保证变量的可见性和禁止指令重排序,但不涉及锁竞争。
在复杂的线程同步和互斥场景,synchronized关键字提供了安全且经过测试的机制来实现线程间的互斥。但需要注意锁的竞争和上下文切换会带来性能开销。
ThreadLocal提供了一种简单的方式来实现线程间的变量隔离和线程上下文传递。它通过为每个线程提供独立的变量副本,避免了锁竞争,并且不涉及上下文切换,访问速度较快。但需要注意及时清理ThreadLocal变量,避免内存泄漏。
综上所述,选择合适的机制取决于具体的使用场景。对于简单的变量读写场景,可以使用volatile关键字。对于复杂的线程同步和互斥场景,synchronized提供了可靠的机制。而ThreadLocal则特别适用于需要变量隔离和线程上下文传递的场景,可以提供简单且高效的解决方案。
总结
在每个线程Thread内部有一个ThreadLocal.ThreadLocalMap类型的成员变量threadLocals,这个threadLocals就是用来存储实际的变量副本的,键值为当前ThreadLocal变量,value为变量副本(即T类型的变量)。 初始时,在Thread里面,threadLocals为空,当通过ThreadLocal变量调用get()方法或者set()方法,就会对Thread类中的threadLocals进行初始化,并且以当前ThreadLocal变量为键值,以ThreadLocal要保存的副本变量为value,存到threadLocals。 然后在当前线程里面,如果要使用副本变量,就可以通过get方法在threadLocals里面查找。
实际的通过ThreadLocal创建的副本是存储在每个线程自己的threadLocals中的;
为何threadLocals的类型ThreadLocalMap的键值为ThreadLocal对象,因为每个线程中可有多个threadLocal变量,就像上面代码中的longLocal和stringLocal;
在进行get之前,必须先set,否则会报空指针异常;如果想在get之前不需要调用set就能正常访问的话,必须重写initialValue()方法。 因为在上面的代码分析过程中,我们发现如果没有先set的话,即在map中查找不到对应的存储,则会通过调用setInitialValue方法返回i,而在setInitialValue方法中,有一个语句是T value = initialValue(), 而默认情况下,initialValue方法返回的是null。
相关文章:
ThreadLocal基本介绍
文章目录 什么是ThreadLocalThreadLocal解决了什么问题ThreadLocal的作用 ThreadLocal的使用场景ThreadLocal的代码示例ThreadLocal的优点ThreadLocal的缺点与volatile、synchronized、ThreadLocal比较 总结 什么是ThreadLocal ThreadLocal是Java中的一个线程本地变量…...
ffmpeg源码编译成功,但是引用生成的静态库(.a)报错,报错位置在xxx_list.c,报错信息为某变量未定义
背景:本文是对上一个文章的补充,在源码编译之前,项目是有完整的ffmpeg编译脚本的,只不过新增了断点调试ffmpeg,所以产生的上面的文章,也就是说,我在用make编译成功后,再去做的源码编…...
2023爱分析·信创云市场厂商评估报告:中国电子云
01 研究范围定义 信创2.0时代开启,信创进程正在从局部到全面、从细分到所有领域延展。在这个过程中,传统的系统集成,也在逐步向信创化、数字化及智能化转变。随着信创产业的发展,企业需要更多的技术支持和服务,而传统的系统集成已…...
网络安全学习笔记——XFF攻击流程
手工注入 手动报错注入,填写格式如:X-Forwarded-For: and updatexml(1,concat(0x7e,(select database()),0x7e),1) or 11 库名 1 and updatexml(1,concat(0x7e,database(),0x7e),1), 表名 1 and updatexml(1,concat(0x7e,(select table_name from…...
微信小程序阻止用户返回上一页,并弹窗给用户确定是否要返回上一页
在onload中调用微信的enableAlertBeforeUnload方法,在首次进入会自动监听当前的页面,在返回的时候会自动弹出弹窗阻止用户返回上一页,点击确定则返回上一页,取消则停留在当前页 onLoad: function(){wx.enableAlertBeforeUnload({…...
LangChain+ChatGLM整合LLaMa模型(二)
开源大模型语言LLaMa LLaMa模型GitHub地址添加LLaMa模型配置启用LLaMa模型 LangChainChatGLM大模型应用落地实践(一) LLaMa模型GitHub地址 git lfs clone https://huggingface.co/huggyllama/llama-7b添加LLaMa模型配置 在Langchain-ChatGLM/configs/m…...
【NLP】训练chatglm2的评价指标BLEU,ROUGE
当进行一定程度的微调后,要评价模型输出的语句的准确性。由于衡量的对象是一个个的自然语言文本,所以通常会选择自然语言处理领域的相关评价指标。这些指标原先都是用来度量机器翻译结果质量的,并且被证明可以很好的反映待评测语句的准确性&a…...
java+springboot+mysql员工工资管理系统
项目介绍: 使用javaspringbootmysql开发的员工工资管理系统,系统包含超级管理员,系统管理员、员工角色,功能如下: 超级管理员:管理员管理;部门管理;员工管理;奖惩管理&…...
FL Studio Producer Edition 21 v21.0.3 Build 3517 Windows/mac官方中文版
FL Studio Producer Edition 21 v21.0.3 Build 3517 Windows FL Studio Producer Edition 21 v21.0.3 Build 3517 Windows/mac官方中文版是一个完整的软件音乐制作环境或数字音频工作站(DAW)。它代表了 25 多年的创新发展,将您创作、编曲、录…...
探索Python数据容器之乐趣:列表与元组的奇妙旅程!
文章目录 零 数据容器入门一 数据容器:list(列表)1.1 列表的定义1.2 列表的下表索引1.3 列表的常用操作1.3.1 列表的查询功能1.3.2 列表的修改功能1.3.3 列表常用方法总结 1.4 补充:append与extend对比1.5 list(列表)的遍历1.6 补…...
Python自动化实战之使用Pytest进行API测试详解
概要 每次手动测试API都需要重复输入相同的数据,而且还需要跑多个测试用例,十分繁琐和无聊。那么,有没有一种方法可以让你更高效地测试API呢?Pytest自动化测试!今天,小编将向你介绍如何使用Pytest进行API自…...
TCP的三次握手以及四次断开
TCP的三次握手和四次断开,就是TCP通信建立连接以及断开的过程 目录 【1】TCP的三次握手过程 ---- TCP建立连接的过程 【2】TCP的四次挥手 ---- TCP会话的断开 注意: 【1】TCP的三次握手过程 ---- TCP建立连接的过程 三次握手的过程:…...
目标检测YOLO实战应用案例100讲-基于视觉与激光雷达信息融合的智能车辆目标检测研究
目录 前言 传感器选型及同步 2.1 各传感器工作原理及性能对比 2.1.1 视觉传感器...
Day 22 C++ STL常用容器——string容器
string容器 概念本质string和char 区别:特点string构造函数构造函数原型 string赋值操作赋值的函数原型示例 string字符串拼接函数原型:示例 string查找和替换函数原型示例 string字符串比较比较方式 字符串比较是按字符的ASCII码进行对比函数原型示例 s…...
使用Socket实现UDP版的回显服务器
文章目录 1. Socket简介2. DatagramSocket3. DatagramPacket4. InetSocketAddress5. 实现UDP版的回显服务器 1. Socket简介 Socket(Java套接字)是Java编程语言提供的一组类和接口,用于实现网络通信。它基于Socket编程接口,提供了…...
【MCU学习】GD32F427VG开发
(一)学习文档和例程 兆易创新GD32 MCU参考资料下载 1.GD232F4xx的Keil芯片支持包 2.标准固件库和示例程序 3.GD32F4xx_固件库使用指南_Rev1.2 4.用户手册:GD32F4xx_User_Manual_Rev2.8_CN 5.数据手册:GD32F427xx_Datasheet_Rev…...
Acwing.877 扩展欧几里得算法
题目 给定n对正整数ai , bi,对于每对数,求出一组ai ,g,使其满足ai* xi bi * yi gcd(ai ,bi)。 输入格式 第一行包含整数n。 接下来n行,每行包含两个整数ai , bi。 输出格式 输出共n行,对于每组ai, bi,…...
基于自组织竞争网络的患者癌症发病预测(matlab代码)
1.案例背景 1.1自组织竞争网络概述 前面案例中讲述的都是在训练过程中采用有导师监督学习方式的神经网络模型。这种学习方式在训练过程中,需要预先给网络提供期望输出,根据期望输出来调整网络的权重,使得实际输出和期望输出尽可能地接近。但是在很多情况下,在人们认知的过程中…...
golang mongodb
看代码吧 package main// 链接案例 https://www.mongodb.com/docs/drivers/go/current/fundamentals/connection/#connection-example // 快速入门 https://www.mongodb.com/docs/drivers/go/current/quick-start/ import ("context""fmt""log"…...
docker中的jenkins去配置sonarQube
docker中的jenkins去配置sonarQube 1、拉取sonarQube macdeMacBook-Pro:~ mac$ docker pull sonarqube:8.9.6-community 8.9.6-community: Pulling from library/sonarqube 8572bc8fb8a3: Pull complete 702f1610d53e: Pull complete 8c951e69c28d: Pull complete f95e4f8…...
详细指南!2026年HR人力资源管理软件排行榜
HR人力资源管理软件是帮助企业数字化管理招聘、入离职、组织人事、薪酬考勤、绩效考核等全流程的系统工具。2026年国内主流HR人力资源管理软件包括Moka、北森、用友、金蝶、飞书、钉钉、薪人薪事、i人事等,其中Moka凭借AI原生能力和一体化产品架构,在中大…...
Snipe-IT容器化部署全攻略:构建企业级IT资产管理系统
Snipe-IT容器化部署全攻略:构建企业级IT资产管理系统 【免费下载链接】snipe-it A free open source IT asset/license management system 项目地址: https://gitcode.com/GitHub_Trending/sn/snipe-it Snipe-IT是一款开源的企业级IT资产与许可证管理系统&am…...
新手零基础入门:用快马平台可视化学习openclaw核心配置
作为一名刚接触机器人开发的新手,我最近在学习openclaw机械爪的配置时遇到了不少困惑。那些抽象的参数名称和数值范围让我一头雾水,直到发现了InsCode(快马)平台的可视化学习方式,才真正理解了这些配置参数的实际意义。下面分享我的学习笔记&…...
终极指南:如何提升实时多人姿态估计算法的可解释性与可信度
终极指南:如何提升实时多人姿态估计算法的可解释性与可信度 【免费下载链接】Realtime_Multi-Person_Pose_Estimation Code repo for realtime multi-person pose estimation in CVPR17 (Oral) 项目地址: https://gitcode.com/gh_mirrors/re/Realtime_Multi-Perso…...
如何在Windows中快速读取Linux分区?Ext2Read完整教程指南
如何在Windows中快速读取Linux分区?Ext2Read完整教程指南 【免费下载链接】ext2read A Windows Application to read and copy Ext2/Ext3/Ext4 (With LVM) Partitions from Windows. 项目地址: https://gitcode.com/gh_mirrors/ex/ext2read 你是否曾经遇到过…...
OpenClaw+SecGPT-14B技能扩展:自动化渗透测试报告生成
OpenClawSecGPT-14B技能扩展:自动化渗透测试报告生成 1. 为什么需要自动化渗透测试报告 每次红队演练结束后,最让我头疼的就是整理渗透测试报告。传统流程需要手动整理Nmap扫描结果、Burp Suite截图、漏洞验证步骤,再粘贴到Word模板里调整格…...
鸿蒙 ArkUI 技巧实战:把商品分类页的“双栏联动 + 吸顶”做顺手
最近做商城类页面时,我发现一个场景几乎每次都会出现:左边是分类,右边是商品列表。 看起来不复杂,但真写起来很容易翻车——左边点了,右边没滚准;右边手动一滑,左边高亮又跟不上;分组…...
目标金额是否能被给定硬币组成或者最少硬币数量
在编程中,判断一个目标金额能否由一组给定的硬币组成,这是一个经典的“硬币找零”或“完全背包”问题。 最常用且高效的解决方法是使用动态规划 核心思路 将这个问题分解成更小的子问题。 是不是在想当前金额,怎么知道能够由哪些已知硬币凑成…...
猫抓:5分钟掌握浏览器资源嗅探神器,轻松下载网页视频和流媒体
猫抓:5分钟掌握浏览器资源嗅探神器,轻松下载网页视频和流媒体 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 还在为网页视…...
MTKClient完全指南:设备调试与固件管理的创新方法 - 适用于开发者与维修工程师
MTKClient完全指南:设备调试与固件管理的创新方法 - 适用于开发者与维修工程师 【免费下载链接】mtkclient MTK reverse engineering and flash tool 项目地址: https://gitcode.com/gh_mirrors/mt/mtkclient MTKClient是一款功能强大的跨平台工具࿰…...
