【Java后端】之 ThreadLocal 详解

想象一下,你有一个工具箱,里面放着各种工具。在多人共用这个工具箱的时候,很容易出现混乱,比如有人拿走了你的锤子,或者你找不到合适的螺丝刀。为了避免这种情况,最好的办法就是每个人都有自己独立的工具箱。

Java 的 ThreadLocal 就相当于给每个线程提供了一个这样的“私有小盒子”。每个线程都可以把自己的东西放进去,不用担心被其他线程干扰。

1. 为什么要用 ThreadLocal?

在多线程编程中,经常会遇到多个线程同时访问共享变量的情况。如果没有做好同步控制,就可能会出现数据不一致的问题,也就是所谓的“线程安全问题”。

ThreadLocal 提供了一种解决线程安全问题的方法,它让每个线程都拥有自己的变量副本,避免了共享变量的竞争。

2. ThreadLocal 怎么工作的?

ThreadLocal 并不是真的给每个线程创建了一个独立的变量,而是通过一个巧妙的设计来实现的。

每个线程内部都有一个 ThreadLocalMap,可以把它看作是一个键值对的集合。ThreadLocal 对象本身作为键,而线程的私有变量作为值。

当线程调用 ThreadLocal.get() 方法时,ThreadLocal 会根据当前线程找到对应的 ThreadLocalMap,然后根据自身作为键取出对应的值。这样就实现了每个线程访问自己私有变量的目的。

3. 如何使用 ThreadLocal?

使用 ThreadLocal 非常简单,通常分为三步:

  • 创建 ThreadLocal 对象: 就像创建一个普通的对象一样,例如 ThreadLocal<String> userName = new ThreadLocal<>();,这里 String 表示私有变量的类型。

  • 设置值: 使用 userName.set("张三"); 方法,把“张三”这个字符串放到当前线程的“小盒子”里。

  • 获取值: 使用 String name = userName.get(); 方法,从当前线程的“小盒子”里取出值。

ThreadLocal 的 常用方法:

public API描述
set(T)设置当前线程的副本
T get()获取当前线程的副本
void remove()移除当前线程的副本
ThreadLocal<S> withInitial(Supplier<S>)创建 ThreadLocal 并指定缺省值创建工厂
protected API描述
T initialValue()设置缺省值

4. 举个栗子

假设一个 Web 应用,每个用户请求都会由一个独立的线程处理。我们可以使用 ThreadLocal 来存储用户的登录信息:

private static final ThreadLocal<String> USER_ID = new ThreadLocal<>();public void processRequest(String userId) {USER_ID.set(userId); // 将用户 ID 存储到 ThreadLocal 中// ... 处理请求 ...String currentUserId = USER_ID.get(); // 获取当前线程的用户 ID// ...USER_ID.remove(); // 使用完毕后清除值
}

5. 内存泄漏的坑

ThreadLocal 使用不当可能会导致内存泄漏。这是因为 ThreadLocalMap 中的键是弱引用,而值是强引用。如果 ThreadLocal 对象被垃圾回收了,但是线程还在运行,那么 ThreadLocalMap 中的值就无法被回收,导致内存泄漏。

为了避免这种情况,最好在使用完 ThreadLocal 后手动调用 remove() 方法清除值,就像上面的例子一样。

6. InheritableThreadLocal:子线程也能继承“小盒子”

InheritableThreadLocal 可以让子线程继承父线程的“小盒子”。也就是说,子线程可以访问父线程设置的线程局部变量。

7. 总结

ThreadLocal 就像给每个线程提供了一个私有的“小盒子”,可以用来存储线程私有的数据,避免线程安全问题。使用起来很简单,但是要注意内存泄漏的坑,记得用完后调用 remove() 方法清理。 选择使用 ThreadLocal 还是其他同步机制,需要根据具体情况进行权衡。 如果只是简单的共享数据,同步机制可能更简单直接。 如果需要维护每个线程独立的数据副本,ThreadLocal 则是更好的选择。

希望这个更通俗易懂的解释能够帮助你理解 ThreadLocal。下期见,谢谢~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

初识适配器模式

适配器模式 引入 生活中的例子&#xff1a;当我们使用手机充电时&#xff0c;充电器起到了转换器的作用&#xff0c;它将家用的220伏特电压转换成适合手机充电的5伏特电压。 适配器模式的三种类型 命名原则&#xff1a;适配器的命名应基于资源如何传递给适配器来进行。 类适配…

第14篇:下一代网络与新兴技术

目录 引言 14.1 下一代网络&#xff08;NGN&#xff09;的定义与特点 14.2 IPv6协议的改进与未来应用 14.3 软件定义网络&#xff08;SDN&#xff09; 14.4 网络功能虚拟化&#xff08;NFV&#xff09; 14.5 量子通信网络 14.6 软件定义广域网&#xff08;SD-WAN&#x…

xlsx xlsx-style-vite 实现前端根据element 表格导出excel且定制化样式 背景 列宽等

前言 先看下最终效果图吧&#xff0c;需要的可以参考我的实现方式 这是最终导出的表格文件 类似这种的&#xff0c;特定单元格需要额外标注&#xff0c;表头也有月份然后细分的&#xff0c;表格组件是这样的 注意 别使用xlsx-style 这个库&#xff0c;太多问题了&#xff0c;…

【C语言刷力扣】1768.交替合并字符串

题目&#xff1a; 解题思路&#xff1a; 将 word1 和 word2 元素依次添加至 ans 的后面。 时间复杂度&#xff1a; &#xff0c; n是word1的长度 m是word2的长度 空间复杂度&#xff1a; char* mergeAlternately(char* word1, char* word2) {int len1 strlen(word1);in…

【Linux】top命令查看CPU、内存使用率、解释

1. top 命令 top 是最常用的实时监控工具之一&#xff0c;可以显示 CPU 的总利用率以及各个进程的 CPU 使用情况。在Linux命令行直接输入top即可查看动态原始数据 top 在 top 命令的输出中&#xff0c;最上面的一行会显示 CPU 的使用情况&#xff1a; us&#xff08;User&a…

图片怎么转文字?11种好用的方法!

如何快速将图片的文字提取出来&#xff0c;可以大量节省手打的时间&#xff0c;无论是截图&#xff0c;或者批量提取照片文字&#xff0c;都经常需要这个操作&#xff01; 作为一名社畜&#xff0c;俺也经常用到各种图片转文字工具&#xff0c;今天通过测评12个主流的图片转文…

面对AI算力需求激增,如何守护数据中心机房安全?

随着人工智能&#xff08;AI&#xff09;技术飞速发展&#xff0c;AI算力需求呈现爆发式增长&#xff0c;导致对数据设备电力的需求指数级攀升。这给数据中心带来前所未有的挑战和机遇&#xff0c;从提供稳定的电力供应、优化高密度的部署&#xff0c;到数据安全的隐私保护&…

OpenVLA-首个开源视觉语言动作大模型

官网&#xff1a;https://openvla.github.io/ 现在大模型已经卷到了机器人领域。 在视觉语言模型&#xff08;VLM&#xff09;的基础上&#xff0c; 加入机器人的动作&#xff08;Action) 这一模态&#xff0c; 视觉语言动作大模型&#xff08;VLA&#xff09;是目前大模型应用…

2024新手攻略:项目管理工具+PMP备考经验不容错过!

&#xff08;一&#xff09;热门工具大盘点 禅道是一款专注于软件开发项目管理的工具。它涵盖了项目管理的各个环节&#xff0c;包括需求管理、任务分配、缺陷跟踪等。禅道的优势在于其对软件开发流程的深入理解和支持&#xff0c;能够帮助开发团队更好地管理项目进度和质量。…

如何应对 Android 面试官 -> ANR 如何优化?线上 ANR 如何监控?

前言 本章主要围绕 ANR 如何监控以及优化&#xff1b; 基本概念 ANR(Android Not Responding) 是指应用程序未响应&#xff0c;Android 系统对于一些事件需要在一定的时间范围内完成&#xff0c;如果超过预订时间未能得到有效响应或者响应时间过长&#xff0c;都会造成 ANR。 …

91 VRRP负载局衡+主备切块 V2

实操四 负载均衡主备 VRRP&#xff08;虚拟路由冗余协议&#xff09;是一种网络协议&#xff0c;用于提高网络的可用性和冗余性。VRRP可以将多个路由设备组成一个虚拟路由器&#xff0c;当主路由设备故障时&#xff0c;自动切换到备用路由设备&#xff0c;从而实现高可用性。 …

Mamba学习笔记(2)—序列数据处理基础

文章目录 (1) RNN&#xff08;Recurrent Neural Networks&#xff09;基本原理代码定义 (2) SLTM (Long Short-Term Memory)基本原理代码定义 (3) GRU (Gated Recurrent Unit)基本原理代码定义 (4) Transformer&#xff08;☆☆☆Attention Is All You Need☆☆☆&#xff09;0…

nginx解决非人类使用http打开的443,解决网安漏扫时误扫443端口带来的问题

一、问题描述 正常访问https的站点时&#xff0c;使用网址https://www.baidu.com&#xff0c;但会有一种错误的访问请求http://www.baidu.com:443&#xff0c;一般都是非人类所为&#xff0c;如漏洞扫描工具&#xff0c;那么请求以后带来的后果是个错误页面 400 Bad Request T…

如何选择合适业务协作平台?—— 板栗看板给你答案

在当今快速发展的商业环境中&#xff0c;团队协作和项目管理变得越来越重要。业务协作平台作为一种工具&#xff0c;可以帮助团队成员进行有效的沟通、任务分配和进度跟踪。这些平台通常具备项目管理、文档共享、实时通讯等功能&#xff0c;以提高团队的工作效率和协作能力。 一…

AttributeError: ‘function‘ object has no attribute ‘decode‘

h5py版本过高&#xff0c;降低版本即可。 1.卸载h5py pip uninstall h5py 卸载后&#xff0c;查看h5py版本&#xff0c;显示这个代表卸载成功。 import h5py print(h5py.__version__) 2. 安装低版本的h5py<3.0.0 目前的版本有&#xff1a; 2.2.1, 2.3.0b1, 2.3.0, 2.3.1,…

如何看ip属于什么地址

在数字化时代&#xff0c;IP地址作为互联网通信的基石&#xff0c;扮演着至关重要的角色。无论是网络管理、安全防护&#xff0c;还是日常的网络访问&#xff0c;理解IP地址的性质和分类都是必不可少的技能。本文将深入探讨如何判断一个IP地址属于哪一类地址&#xff0c;并详细…

阿里云验证码短信发送服务搭建(flask)

参考&#xff1a;https://next.api.aliyun.com/api-tools/sdk/Dysmsapi?version2017-05-25&languagejava-async-tea&tabprimer-doc 我们需要思考验证服务一些要求&#xff1a; 1.验证码只能被验证一次&#xff0c;所以需要状态字段 2.验证码有失效时间&#xff0c;超…

C++STL--------list

文章目录 一、list链表的使用1、迭代器2、头插、头删3、insert任意位置插入4、erase任意位置删除5、push_back 和 pop_back()6、emplace_back尾插7、swap交换链表8、reverse逆置9、merge归并10、unique去重11、remove删除指定的值12、splice把一个链表的结点转移个另一个链表13…

利用Spring Boot实现信息化教学平台

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理信息化在线教学平台的相关信息成为必然。开…

AI金融攻防赛:YOLO理论学习及赛题进阶思路(DataWhale组队学习)

引言 大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年10月学习赛的AI金融攻防赛学习总结文档。本文主要讲解如何在金融场景凭证篡改检测中应用YOLO算法。我们将从模型概述、数据准备、训练流程以及模…