ThreadLocal的三种使用场景(转发)

volatile、ThreadLocal的使用场景和原理 java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁单独获得这个变量。当线程没有结束,但是ThreadLocal已经被回收,则可能导致线程中存在ThreadLocalMapnull, Object>的键值对,造成内存泄露。虽然ThreadLocal的get,set方法可以清除ThreadLocalMap中key为null的value,但是get,set方法在内存泄露后并不会必然调用,所以为了防止此类情况的出现,我们有两种手段。示例2(Session管理) 阅读详情

目录

场景一:

场景二:

场景三:

慎用的场景


ThreadLocal包含了四个方法:

void set(Object value) 设置当前线程的线程局部变量的值。

public Object get() 该方法返回当前线程所对应的线程局部变量。 

public void remove() 将当前线程局部变量的值删除,其目的是为了减少内存使用,加快内存回收。 

protected Object initialValue() 返回该线程局部变量的初始值,该方法是一个protected的方法,
目的是为了让子类覆盖而设计的

在实际的工作中,我们在哪些场景下会用到ThreadLocal呢?
这里笔者整理了三个使用场景。

场景一:

代替参数的显式传递当我们在写API接口的时候,通常Controller层会接受来自前端的入参,当这
个接口功能比较复杂的时候,可能我们调用的Service层内部还调用了很多其他的很多方法,通常情况下,我们会在每个调用的方法上加上需要传递的参数。但是如果我们将参数存入ThreadLocal中,那么就不用显式的传递参数了,而是只需要ThreadLocal中获取即可。这个场景其实使用的比较少,一方面显式传参比较容易理解,另一方面我们可以将多个参数封装为对象去传递。

场景二:

全局存储用户信息在现在的系统设计中,前后端分离已基本成为常态,分离之后如何获取用户信息就成了一件麻烦事,通常在用户登录后, 用户信息会保存在Session或者Token中。这个时候,我们如果使用常规的手段去获取用户信息会很费劲,拿Session来说,我们要在接口参数中加上HttpServletRequest对象,然后调用 getSession方法,且每一个需要用户信息的接口都要加上这个参数,才能获取Session,这样实现就很麻烦了。在实际的系统设计中,我们肯定不会采用上面所说的这种方式,而是使用ThreadLocal,我们会选择在拦截器的业务中, 获取到保存的用户信息,然后存入ThreadLocal,那么当前线程在任何地方如果需要拿到用户信息都可以使用ThreadLocal的get()方法 (异步程序中ThreadLocal是不可靠的)对于笔者而言,这个场景使用的比较多,当用户登录后,会将用户信息存入Token中返回前端,当用户调用需要授权的接口时,需要在header中携带 Token,然后拦截器中解析Token,获取用户信息,调用自定义的类(AuthNHolder)存 ThreadLocal中,当请求结束的时候,将ThreadLocal存储数据清空, 中间的过程无需在关注如何获取用户信息,只需要使用工具类的get方法即可。

场景三:

解决线程安全问题在Spring的Web项目中,我们通常会将业务分为Controller层,Service层,Dao层,我们都知道@Autowired注解默认使用单例模式,那么不同请求线程进来之后,由于Dao层使用单例,那么负责数据库连接的Connection也只有一个,如果每个请求线程都去连接数据库,那么就会造成线程不安全的问题,Spring是如何解决这个问题的呢?在Spring项目中Dao层中装配的Connection肯定是线程安全的,其解决方案就是采用ThreadLocal方法,当每个请求线程使用Connection的时候,都会从ThreadLocal获取一次,如果为null,说明没有进行过数据库连接,连接后存入ThreadLocal中,如此一来,每一个请求线程都保存有一份 自己的Connection。于是便解决了线程安全问题ThreadLocal在设计之初就是为解决并发问题而提供一种方案,每个线程维护一份自己的数据,达到线程隔离的效果。

慎用的场景

线程池中线程调用使用ThreadLocal 由于线程池中对线程管理都是採用线程复用的方法。在线程池中线程非常难结束甚至于永远不会结束。这将意味着线程持续的时间将不可预測,甚至与JVM的生命周期一致
异步程序中,ThreadLocal的參数传递是不靠谱的, 由于线程将请求发送后。就不再等待远程返回结果继续向下运行了,真正的返回结果得到后,处理的线程可能是其他的线程。Java8中的并发流也要考虑这种情况
使用完ThreadLocal ,最好手动调用 remove() 方法,防止出现内存溢出,因为中使用的key为ThreadLocal的弱引用, 如果ThreadLocal没有被外部强引用的情况下,在垃圾回收的时候会被清理掉的,但是如果value是强引用,不会被清理, 这样一来就会出现 key 为 null 的 value。
 

Unity机械拆装实战:5步搞定发动机模型交互式装配(附完整代码) 本文详细介绍了在Unity中实现高交互性机械拆装仿真的完整流程。以发动机模型为例,通过5个核心步骤:项目初始化与模型准备、核心交互实现、智能装配逻辑、场景管理与相机控制、进阶优化与扩展,系统讲解了从零构建交互式装配功能的方法,并提供了完整的代码示例。 阅读详情

相关推荐

致远OA公文管理模块相关操作

致远oa协同办公系统 公文管理模板 相关操作

weixin_59666050的博客 4278

【并发编程学习篇】导致JVM内存泄露的ThreadLocal详解

ThreadLocal对于每一位Java读者而言我想可能都不陌生,因为面试基本都会被问到。 ThreadLocal包含了四个方法: void set(Object value) 设置当前线程的线程局部变量的值。 public Object get() 该方法返回当前线程所对应的线程局部变量。 public void remove() 将当前线程局部变量的值删除,其目的是为了减少内存使用,加快内存回收。 protected Object initialValue() 返回该线程局部变量的初始值,.

一个勤勤恳恳的程序猿 1万+

zemax光线光扇图

通过入瞳某一坐标(PX,PY)的光线在像面上有唯一的位置(EX,EY),以EX,EY为纵坐标,以PX,PY为横坐标,分别建立坐标系,把通过入瞳的光线都在坐标系里描点就得到了光扇图。对于视场内任意一点,取其子午面内的光线,以光线在光阑面上的透射点坐标为横坐标,同时以该光线在像面上的坐标为纵坐标,描出所有点,构成的图形即为子午面光扇图。在焦点位置,曲线的斜率为0,也就是说,不管入射时的横坐标(光阑面上的位置)是多少,离轴多远,都将汇聚在焦点处。此时,子午面和弧矢面有不同的分布,两条曲线不重合。

fendoudecheng的博客 8103

ThreadLocal 适合用在哪些实际生产的场景中?

在这种情况下,每个 Thread 内都有自己的实例副本,且该副本只能由当前 Thread 访问到并使用,相当于每个线程内部的本地变量,这也是 ThreadLocal 命名的含义。因为每个线程独享副本,而不是公用的,所以。

jcc4261的博客 2976

Chapter 5 Gate Drivers and Level Shifters

Gate driver如下图所示, 包括功率管(带保护), Gate driver, Level shifter, Gate Supply 和Dead-time control.

2304_76736886的博客 2243

AI Agent Harness Engineering 创业PMF验证工具:用户满意度+留存率+业务指标监测表

在AI Agent创业的浪潮中,我们看到了无数产品如雨后春笋般涌现,但最终能够真正找到PMF并存活下来的却寥寥无几。根据CB Insights的数据,创业公司失败的首要原因(占42%)是"没有市场需求"——换句话说,就是没有找到PMF。AI Agent产品由于其特殊性(交互范式的变革、技术复杂度高、用户期望管理困难等),PMF验证变得更加具有挑战性。传统的SaaS产品PMF验证框架虽然有参考价值,但无法完全适用于AI Agent这种新型产品形态。

AI智能探索者的博客 335

什么是ThreadLocal?应用场景有哪些?

【代码】什么是ThreadLocal?应用场景有哪些?

mengbotian的博客 322

Macbook Pro上如何修改brew源

一、需求说明 我的macbook电脑安装了中科大的brew源码,发现安装gpg工具失败,其他工具可以正常安装,为了能将gpg安装成功,就找了找切换brew源的方案,记录如下。 二、切换至国内源 由于使用github默认源有可能存在路径远或者部分服务访问超时的原因,切换至国内源可以提速。 2.1 替换brew.git $ cd "$(brew --repo)" # 中国科大: $ git remote set-url origin https://mirrors.ustc.edu.cn/brew.git #

bufegar0的博客 1080

ThreadLocal 本地线程变量介绍及使用场景

一、本地线程变量使用场景 并发应用的一个关键地方就是共享数据。如果你创建一个类对象,实现Runnable接口,然后多个Thread对象使用同样的Runnable对象,全部的线程都共享同样的属性。这意味着,如果你在一个线程里改变一个属性,全部的线程都会受到这个改变的影响。 有时,你希望程序里的各个线程的属性不会被共享。 Java 并发 API提供了一个很清楚的机制叫本地线程变量即ThreadLocal。 模拟ThreadLocal类实现:线程范围内的共享变量,每个线程只能访问他自己的,不能访问别的线程

猿小许的博客 1288

DevEco Studio在初始化时出现Installing pnpm@8.13.1...npm ERR! code ETIMEDOUTnpm ERR! syscall connectnpm E

npm的仓库源设置的有问题,下载不了鸿蒙相关组件,所以你的启动依赖都没有,或者以前下载过npm,使用的源改的乱七八糟了。以前安装过前端相关的node.js的话,启动的时候记得使用管理远权限。(DevEco Studio)就出错,npm显示超时。

qq_56392862的博客 2628

服务器能效测试工具BenchSEE使用方法简介

BenchSEE是由中国标准化研究院开发的一款针对服务器产品能效测试的基准软件。BenchSEE基准的设计参考了全球众多服务器厂家、芯片厂家、能效认证机构和IT节能领域科研机构的意见,旨在满足服务器市场应用对能效测评的需求。BenchSEE基准负载工具支持的服务器类型包括:机架服务器、刀片服务器多节点服务器和机柜服务器等,服务器可以配的最大外理器个数包括:1P,2P和4P等。测试基准涵盖服务器关键部件:CPU,内存和存储介质三大基础部件。

MQWYY3的博客 4222

ThreadLocal原理及使用场景

ThreadLocal ​ ThreadLocal意为线程本地变量,用于解决多线程并发时访问共享变量的问题。 ​ 所谓的共享变量指的是在堆中的实例、静态属性和数组;对于共享数据的访问受Java的内存模型(JMM)的控制,其模型如下: 【参考:《Java并发编程的艺术》P22】 每个线程都会有属于自己的本地内存,在堆(也就是上图的主内存)中的变量在被线程使用的时候会被复制一个副本线程的本地内存中,当线程修改了共享变量之后就会通过JMM管理控制写会到主内存中。 ​ 很明显,在多线程的场景下,当有多个线程对共享

weixin_44184990的博客 7万+

论文必备 - YOLOv12热力图可视化,支持指定模型,指定显示层,设置置信度,以及10种可视化实现方式

本文带来的是YOLOv12热力图可视化功能,支持,以及。我们经常看到一些论文里绘制了不同的热力图,一方面能够直观的感受其模型的有效性,另一方面也丰富了论文内容。特别是在使用了注意力模块的网络中,热力图就可以验证注意力机制是否真正聚焦到了预期的重要特征上,以便对模型的有效性和合理性进行评估。例如这篇文章中展示的,就很能够表达作者改进后的模型相比之前模型的优越性。

Limiiiing的博客 1706

解决异步任务中访问ThreadLocal报错的方案及实现

当开发软件程序时,我们通常需要异步记录操作日志。操作日志可以用于跟踪系统的运行情况、查询问题以及审计目标的。然而,在某种情况下,我们可能会遇到在异常任务中访问ThreadLocal的信息时报错。这种错误可能会导致无法正确获取用户信息,并影响到日志记录的准确性和完整性。本文主要介绍了三种解决方案。

霁晨晨晨的博客 3万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

ThreadLocal三种使用场景

关于ThreadLocal JDK1.2的版本中就提供java.lang.ThreadLocal类,每一个ThreadLocal能够放一个线程级别的变量, 它本身能够被多个线程共享使用,并且又能够达到线程安全的目的,且绝对线程安全。 ThreadLocal包含了四个方法: void set(Object value) -- 设置当前线程的线程局部变量的值。 public Object ...

Mynah886的博客 3232

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

ThreadLocal 是什么?有哪些使用场景?

ThreadLocal 是什么?有哪些使用场景? ThreadLocal 是线程本地存储,在每个线程中都创建了一个 ThreadLocalMap 对象,每个线程可以访问自己内部 ThreadLocalMap 对象内的 value。 经典的使用场景是为每个线程分配一个 JDBC 连接 Connection。这样就可以保证每个线程的都在各自的 Connection 上进行数据库的操作,不会出现...

ConstXiong 5万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

ThreadLocal使用场景与原理

目录 ThreadLocal的使用场景 ThreadLocal与synchronized的区别 Thread、ThreadLocal及ThreadLocalMap的关系 调用remove()方法避免内存泄漏 ThreadLocal的使用场景 ThreadLocal 用作保存每个线程独享的对象,为每个线程都创建一个副本,这样每个线程都可以修改自己所拥有的副本, 而不会影响其他线程的副本,确保了线程安全。 ThreadLocal 用作每个线程内需要独立保存信息,以便供其他方法更方便地获取该信息的场

学无止境 1万+

ThreadLocal 常见使用场景

ThreadLocal 之前一篇文章我已经和大家探讨了ThreadLocal的实现原理,并分析了源码,现在这篇文章带大家了解一下其常见的使用场景,在最近的项目中我也用到了。首先复习下其包含的四个方法: void set(Object value) // 设置当前线程的线程局部变量的值。 public Object get() // 该方法返回当前线程所对应的线程局部变量。 public void remove()// 将当前线程局部变量的值删除,其目的是为了减少内存使用,加快内存回收。 protected

m0_61802230的博客 7522

ThreadLocal 的原理和使用场景

提供了线程本地存储,保证每个线程都有自己独立的变量副本,适用于场景如会话管理、数据库连接、事务管理、跨层数据传参等。它通过为每个线程存储本地变量,并通过弱引用机制来避免内存泄漏。使用可以减少锁的使用和同步开销,但需要谨慎处理内存泄漏风险。

x737510的博客 2235

【源码阅读】一文搞懂 ThreadLocal 原理以及使用场景

无论是工作还是面试,我们都会跟打交道,今天就跟大家聊聊哈~ThreadLocal是什么?为什么要使用ThreadLocal一个ThreadLocal的使用案例ThreadLocal的原理为什么不直接用线程id作为ThreadLocalMap的key为什么会导致内存泄漏呢?是因为弱引用吗?Key为什么要设计成弱引用呢?强引用不行?InheritableThreadLocal保证父子线程间的共享数据ThreadLocal的应用场景和使用注意点。

欢迎来到 程序猿 的博客 6564

ThreadLocal 的使用场景

是 Java 提供的一种线程局部存储机制,它为每个使用该变量的线程都提供一个独立的副本。换句话说,一个变量在不同线程中是独立存储的,线程之间不会相互干扰。在多线程环境下,每个线程需要独立拥有一个变量的副本,而不与其他线程共享。例如,每个线程需要拥有一个独立的数据库连接或配置信息。在需要保存线程上下文信息的情况下,可以使用 ThreadLocal。例如,Web 应用程序中的用户认证信息、请求的 HttpServletRequest 对象等需要在整个请求处理过程中共享。

Flying_Fish_roe的博客 1226

ThreadLocal的使用场景及使用方式

两大使用场景-ThreadLocal的用途 典型场景1:每个线程需要一个独享的对象(通常是工具类,典型需要使用的类有SimpleDateFormat和Random) 典型场景2:每个线程内需要保存全局变量(例如在拦截器中获取用户信息),可以让不同方法直接使用,避免参数传递的麻烦。 典型场景1:每个线程需要一个独享的对象 每个Thread内有自己的实例副本,不共享; 举例:SimpleDateFormat。(当多个线程共用这样一个SimpleDateFormat,但是这个类是不安全的) 2..

HelloWorld搬运工 4842

ThreadLocal使用场景

在Java的多线程编程中,为保证多个线程对共享变量的安全访问,通常会使用synchronized来保证同一时刻只有一个线程对共享变量进行操作。 但在有些情况下,synchronized不能保证多线程对共享变量的正确读写。例如类有一个类变量,该类变量会被多个类方法读写,当多线程操作该类的实例对象时,如果线程对类变量有读取、写入操作就会发生类变量读写错误,即便是在类方法前加上synchronized也

indexchen的专栏 1万+

Java-ThreadLocal三种使用场景

关于ThreadLocal JDK1.2的版本中就提供java.lang.ThreadLocal类,每一个ThreadLocal能够放一个线程级别的变量, 它本身能够被多个线程共享使用,并且又能够达到线程安全的目的,且绝对线程安全。 ThreadLocal包含了四个方法: void set(Object value)设置当前线程的线程局部变量的值。 public Object get()该方法返回当前线程所对应的线程局部变量。 public void remove()将当前线程局部变量的值删除,其目的是为了

qq_33240556的博客 821
上一篇: 深入理解Maven
下一篇: Redis——实现优惠券秒杀
486过于烦躁
博客等级 码龄6年 17粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值