ThreadLocal 详解(一)

server/2024/10/18 23:25:59/

一、ThreadLocal简介

        Threadlocal叫做线程变量,意思是Treadlocal中填充的变量数据当前线程,该变量对其他线程而言是隔离的,并且变量在整个的生命周期有效。Threadlocal会为每个线程中都创建一个副本,那么每个线程可以访问自己内部的副本变量。

        Threadlocal内部通过Ma来存储每一个线程的变量副本,Map的Key就是当前的Threadlocal,Value值就是我们set的那个值,每次线程在get时候,都从自己的变量中取值,所以不会存在线程安全问题;注意:使用Thradlocal后,一直要手动remove(),否则会造成OOM异常;Threadlocal提供了线程本地实例,它与普通变量的却别在于每个使用该变量的线程都会初始化一个完全独立的实例副本。Threadlocal变量通常被private static修饰。当一个线程结束时,他所使用的Threadlocal相对的实例副本都可被回收。

二、ThreadLocal可以解决多线程环境下的上下文传递问题,它提供了以下主要功能

  •  上下文隔离:每个线程可以通过Threadlocal独立存储和访问自己的数据,不同的线程之间数据相互隔离,避免了线程间数据的冲突和竞争条件;
  •  线程安全:Threadlocal提供了线程级别的数据副本,每个线程都可以独立的操作自己的数据,无需考虑并发访问的同步问题。这样可以简化编发编程的复杂性,并提高程序的性能。
  •  线程上下文传递:在多线程的环境中,可能需要在不同的方法或组件中传递上下文信息,例如用户信息、请求跟踪ID等。Threadlocal可以同一线程内共享上下文信息,,而无需显示传递参数。        

三、ThreadLocal与Synchronized的区别

        Threadlocal<T>其实是与线程绑定的一个变量。Threadlocal和synchonzied都用于结局并发问题,但是Threadlocal与synchronized有本质区别。

  1. Synchroized用于线程间的数据共享,而Thradlocal则用于线程间的数据隔离。
  2. Synchroized是利用锁的机制,使变量或代码块在某一时刻只能被一个线程访问。而Threadlocal每一个线程都提供了变脸的副本,使得每个线程在某一时间访问到的并不是同一对象,这样就隔离了多个线程对数据的数据共享。而Synchroized却正好相反,它用于在多个线程间通信时能够获得数据共享;

四、ThreadLocal使用场景

  • 记录每次请求用户信息

ThreadLocal代码:

java">public class RequestHolder {private static final ThreadLocal<SysUser> userHolder = new ThreadLocal<SysUser>();public static void setUser(SysUser sysUser) {userHolder.set(sysUser);}public static SysUser getUser() {return userHolder.get();}public static void remove() {userHolder.remove();}
}

获取用户值

java">// 1、拦截器获取用户信息
// 2、记录到ThreadLocal中
@Component
public class AuthenticationHandlerInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.debug("进入拦截器,URL:{}", request.getServletPath());// 加入用户全局信息RequestHolder.setUser(userInfo);return true;}........
}// 3、使用时通过get()方法获取值
@RestController
@RequestMapping
public class Controller {.....@GetMapping("/test")public String test() {// 从ThreadLocal获取数据RequestHolder.getUserId();return "访问成功";}.....
}

结尾:喜欢的朋友点个赞吧!


http://www.ppmy.cn/server/96599.html

相关文章

c++物理引擎库-Bullet Physics

在游戏开发、虚拟现实和计算机图形学等领域&#xff0c;准确而高效的物理模拟是创建逼真场景和交互体验的关键。Bullet Physics 库作为一款出色的开源物理引擎&#xff0c;为开发者提供了强大的工具来实现各种复杂的物理效果。 Bullet Physics 库具有以下显著特点&#xff1a;…

[C++] vector对比list deque的引出

文章目录 list与vector的对比双端队列dequedeque的特性deque的底层实现原理内存结构块表&#xff08;Block Array&#xff09;块&#xff08;Block&#xff09; 插入与删除两端插入两端删除 随机访问如何计算位置 迭代器设计 总结 list与vector的对比 vector与list都是STL中非…

功能实现——通过阿里云 OSS 实现文件管理

目录 1.需求分析2.阿里云 OSS 开通与配置2.1.登录阿里云官网2.2.搜索 OSS 服务并开通2.3.OSS 配置 3.在项目使用阿里云 OSS3.1.项目环境搭建3.2.代码实现3.2.1.将本地文件上传到阿里云 OSS3.2.2.将前端传入的文件上传到阿里云 OSS3.2.3.下载文件到本地2.3.4.流式下载3.2.4.OSSC…

Java处理大数据的技巧

大数据处理是现代计算机科学中的一个重要领域&#xff0c;通过高效的算法和工具&#xff0c;我们可以从大量数据中提取有价值的信息。本文将介绍一些处理大数据的技巧和策略&#xff0c;并讨论如何通过Java与MySQL实现高效的大数据处理。 一、什么是大数据处理&#xff1f; 大…

c# 逻辑运算符和条件运算符

前言 在 C# 中&#xff0c;&&、|| 用于处理布尔值&#xff08;true 和 false&#xff09;&#xff0c;而&、|、^ 位运算符可以用于按位操作整数。 后者总是计算其两个操作数 而前者可能不会计算第二个操作数&#xff0c;这取决于第一个操作数的值。 非短路逻辑运…

程序员在AI时代的自我进化:深耕技术还是拓宽视野?

随着AIGC&#xff08;如ChatGPT、Midjourney、Claude等&#xff09;大语言模型的接连涌现&#xff0c;AI辅助编程工具正在迅速普及&#xff0c;程序员的工作方式也因此正经历着深刻的变革。面对这一趋势&#xff0c;程序员们不禁要问&#xff1a;我们应该如何应对&#xff1f;是…

使用ventoy制作U盘安装centos8

使用ventoy制作U盘安装centos8 参考&#xff1a;https://blog.51cto.com/u_14120/11118656 推荐这个https://www.zhihu.com/question/290783457/answer/3103388484 1、ventoy官网 https://www.ventoy.net/en/download.html 2、下载完成直接制作u盘启动盘 4、将下载iso镜像…

Docker 镜像仓库搭建

Docker镜像仓库的搭建是一个涉及多个步骤的过程&#xff0c;以下是详细的搭建步骤&#xff1a; 一、准备工作 安装Docker&#xff1a; 确保在主机上安装了Docker引擎。可以在Docker的官方网站上找到相应的安装指南。 确定仓库需求&#xff1a; 根据使用场景&#xff0c;确定仓…