Thread Local六连问,你扛得住吗?

一、Thread Local 是什么?

线程本地变量。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每个线程都可以独立地改变自己的副本,而不影响其他线程,做到了线程隔离。

二、Thread Local 的实现原理是什么?
ThreadLocal原理 · 进击的java菜鸟

ThreadLocal有一个静态内部类ThreadLocalMap, ThreadLocalMap又包含一个Entry数组,Entry本身是一个弱引用,它的key是指向ThreadLocal的弱引用,Entry具备了保存key value键值对的能力。弱引用的目的是为了防止内存泄漏,如果是强引用那么ThreadLocal对象除非线程结束否则无法被回收,弱引用则会在下一次GC的时候被回收。

但是这样还是会存在内存泄露的问题,假如key和ThreadLocal对象被回收之后,entry中就存在key为null,但是value有值的entry对象,但是永远没办法被访问到,同样除非线程结束运行。但是只要ThreadLocal使用恰当,在使用完之后调用remove方法删除Entry对象,实际上是不会出现这个问题的。

ThreadLocal 是一个线程的本地变量,也就意味着这个变量是线程独有的,是不能与其他线程共享的,这样就可以避免资源竞争带来的多线程的问题,这种解决多线程的安全问题和lock(这里的lock 指通过synchronized 或者Lock 等实现的锁) 是有本质的区别的:

  1. lock 的资源是多个线程共享的,所以访问的时候需要加锁。
  2. ThreadLocal 是每个线程都有一个副本,是不需要加锁的。
  3. lock 是通过时间换空间的做法。
  4. ThreadLocal 是典型的通过空间换时间的做法。

三、Thread Local 有什么作用?

ThreadLocal的作用是提供线程内的局部变量,在多线程环境下访问时能保证各个线程内的ThreadLocal变量各自独立。 也就是说,每个线程的ThreadLocal变量是自己专用的,其他线程是访问不到的。

四、Thread Local 如何使用?

Thread Local 的使用方法是通过 ThreadLocal 类创建一个 ThreadLocal 对象,并通过设置和获取方法来操作其中的变量副本。在线程中通过调用 set 方法可以设置当前线程的变量副本的值,在其他地方通过 get 方法可以获取当前线程的变量副本的值。

定义了一个 ThreadLocal 变量 threadLocal,它的泛型类型是 Integer。然后创建了两个线程,并分别启动它们。每个线程都会执行一个 Runnable 实现类 MyRunnable,在这个类中,使用了 ThreadLocal 来保存每个线程的局部变量值,并在 run 方法中进行设置、获取和清除操作。

通过这个示例,可以看到不同线程之间的局部变量互不干扰,每个线程都可以独立地访问和修改自己的局部变量值,而不会影响其他线程。

public class ThreadLocalExample {// 定义一个 ThreadLocal 变量private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();public static void main(String[] args) {// 创建两个线程,并启动Thread thread1 = new Thread(new MyRunnable("Thread-1"));Thread thread2 = new Thread(new MyRunnable("Thread-2"));thread1.start();thread2.start();}static class MyRunnable implements Runnable {private String name;public MyRunnable(String name) {this.name = name;}@Overridepublic void run() {// 设置当前线程的局部变量值threadLocal.set((int) (Math.random() * 100));// 获取当前线程的局部变量值并打印System.out.println("Thread " + name + " ThreadLocal value: " + threadLocal.get());// 清除当前线程的局部变量值threadLocal.remove();}}
}

五、Thread Local 有哪些常见使用场景?

  • 线程安全的对象存储: 在多线程环境中,有时候需要每个线程都拥有自己的对象实例,以避免线程安全问题。ThreadLocal 可以用来存储线程私有的对象实例,每个线程都可以独立地访问自己的对象实例,而不会受到其他线程的影响。

  • Web 应用中的用户身份信息传递: 在 Web 应用中,用户的身份信息通常会在多个组件或层之间传递,例如在拦截器、过滤器、Servlet、Spring MVC 控制器等中。使用 ThreadLocal 可以方便地将用户身份信息存储在当前线程中,在整个请求处理过程中都可以方便地获取到用户身份信息,而不必在每个方法参数中传递。

  • 数据库连接管理: 在需要频繁地访问数据库的应用中,为了提高性能通常会使用连接池管理数据库连接。ThreadLocal 可以用来存储线程私有的数据库连接,保证每个线程都能够独立地获取自己的数据库连接,而不会出现多线程并发访问数据库连接的问题。

  • 事务管理: 在使用事务进行数据库操作时,通常会将事务与当前线程进行绑定,以确保在同一个事务中执行的多个数据库操作能够在同一个事务上下文中进行。ThreadLocal 可以用来存储当前线程的事务上下文,保证每个线程都能够独立地获取自己的事务上下文,而不会影响其他线程的事务操作。

  • 线程上下文信息传递: 在某些情况下,需要在线程之间传递一些上下文信息,例如请求标识、日志跟踪信息等。ThreadLocal 可以用来存储线程私有的上下文信息,每个线程都可以独立地获取自己的上下文信息,而不会影响其他线程。

六、Thread Local 有哪些注意事项?

  1. 内存泄漏:要及时清理不再需要的 Thread Local 变量,避免长时间持有对对象的引用导致内存泄漏。
  2. 并发安全:尽量避免在多个线程之间共享可变状态的 Thread Local 变量,以确保线程安全。
  3. 全局状态:过度使用 Thread Local 可能会导致程序变得难以理解和维护,应该谨慎使用,并考虑是否有更好的解决方案。
  4. 性能影响:大量的 Thread Local 变量可能会增加线程间切换的开销,需要权衡使用场景和性能影响。

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

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

相关文章

windows hash简介

一、hash简介 1、Windows系统使用两种方法对用户的密码进行哈希处理。它们分别是LAN Manager(LM)哈希和 NT LAN Manager(NTLM)哈希 2、所谓哈希(hash)&#xff0c;就是使用一种加密函数进行计算后的结果。这个加密函数对一个任意长度的 字符串数据进行一次数学加密函数运算…

电厂三维人员定位系统的应用与优势有哪些?

在电力行业的快速发展中&#xff0c;电厂的安全生产和管理显得尤为重要。近年来&#xff0c;随着信息技术的不断进步&#xff0c;电厂三维人员定位系统逐渐成为电厂安全管理的新利器。该系统利用三维技术&#xff0c;实现对电厂内部人员位置的实时监控与定位&#xff0c;大大提…

主机加固的最后一米防护

智慧互联的浪潮正席卷全球&#xff0c;它不仅重塑了传统的工业格局&#xff0c;也催生了无数创新的商业模式。随着物联网和互联网技术的飞速发展&#xff0c;智能化、自动化、联网化已成为未来各个行业的发展方向。然而&#xff0c;智慧物联的开放性、系统的漏洞以及基于用户、…

初识JAVA中的包装类,时间复杂度及空间复杂度

目录&#xff1a; 一.包装类 二.时间复杂度 三.空间复杂度 一.包装类&#xff1a; 在Java中&#xff0c;由于基本类型不是继承自Object&#xff0c;为了在泛型代码中可以支持基本类型&#xff0c;Java 给每个基本类型都对应了一个包装类型。 1 基本数据类型和对应的包装类 &am…

【Lua】IntelliJ IDEA 写注释或选中变量单词时偶尔会选中相邻的内容或下一行内容

例如: --UI代码local a 0 当你想在a变量上方加一行 --UI代码注释时&#xff0c;会发现敲打daima中文拼音时&#xff08;还未按回车&#xff09;就会选中当前行以及下一行前半部分。 打完按空格就会变成这样子&#xff01; 原因是因为开启了英文检测&#xff0c;需要关掉它。 …

基于SVm和随机森林算法模型的中国黄金价格预测分析与研究

摘要 本研究基于回归模型&#xff0c;运用支持向量机&#xff08;SVM&#xff09;、决策树和随机森林算法&#xff0c;对中国黄金价格进行预测分析。通过历史黄金价格数据的分析和特征工程&#xff0c;建立了相应的预测模型&#xff0c;并利用SVM、决策树和随机森林算法进行训…

Gradio 案例——将文本文件转为词云图

文章目录 Gradio 案例——将文本文件转为词云图界面截图依赖安装项目目录结构代码 Gradio 案例——将文本文件转为词云图 利用 word_cloud 库&#xff0c;将文本文件转为词云图更完整、丰富的示例项目见 GitHub - AlionSSS/wordcloud-webui: The web UI for word_cloud(text t…

Python脚手架系列-PyQt5

记录PyQt模块使用中的一些常常复用的代码 其他 导入界面 import sysfrom PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QApplication, QMainWindow from UI.MainWindow import Ui_MainWindow # 导入UI界面的类以供继承class MyApp(QMainWindow, Ui_MainWindow):de…

未来以来!鸿蒙生态爆发式增长,程序员新出路火速Get。

鸿蒙生态取得爆发式增长&#xff01; 鸿蒙生态建设速度突飞猛进&#xff0c;不仅有超4000款应用加速开发&#xff0c;众多头部SDK伙伴也在积极加入&#xff0c;为开发者提供构建鸿蒙原生应用所需的多项能力。近期&#xff0c;友盟移动统计SDK、神策数据SDK、阿里云日志服务SDK…

Latex中标注通讯作者

** 直接使用脚注&#xff0c;不用添加宏包 多个同地址的并列&#xff0c;建议加点空格&#xff0c;好看一些 ** \title{xxxxxxxxxxxxxxxxxxx}\author{xxxxxxxxxxxxxxxxxxx\footnote{Corresponding author} ,bbbbbbbbbbbbbbbbbbb}\address{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx…

免费,Scratch蓝桥杯比赛历年真题--第15届蓝桥杯STEMA真题-2024年3月份(含答案解析和代码)

第15届蓝桥杯STEMA真题-2024年3月份 一、单选题 答案&#xff1a;D 解析&#xff1a;y坐标正值表示上&#xff0c;负值表示下&#xff0c;故答案为D。 答案&#xff1a;C 解析&#xff1a;18<25为真&#xff0c;或关系表示一真即为真&#xff0c;故答案为C。 答案&#xff…

Android设备获取OAID调研和实现

什么是OAID、AAID、VAID OAID OAID是"Android ID"&#xff08;安卓ID&#xff09;的一种替代方案&#xff0c;其全称为"Open Anonymous Identifier"&#xff08;开放匿名标识符&#xff09;。 因传统的移动终端设备标识如国际移动设备识别码&#xff08;…

冯喜运:6.5黄金原油今日行情趋势分析及操作策略

【黄金消息面分析】&#xff1a;在全球经济的波动中&#xff0c;美元和黄金市场的表现一直是投资者关注的焦点。最近&#xff0c;市场情绪和经济数据的波动对这两个市场产生了显著的影响。周二欧市早盘&#xff0c;现货黄金价格出现短线回调&#xff0c;金价跌破2340美元/盎司&…

数组中的第K个最大元素 ---- 分治-快排

题目链接 题目: 分析: 这道题很明显是一个top-K问题, 我们很容易想到用堆排序来解决, 堆排序的时间复杂度是O(N*logN), 不符合题意, 所以我们可以用另一种方法:快速选择算法, 他的时间复杂度为O(N)快速选择算法, 其实是基于快排, 进行修改而成, 我们还是使用将"将数组分…

【Godot4自学手册】第四十一节背包系统(一)UI设置

各位同学&#xff0c;好久没有更新笔记了&#xff0c;今天开始&#xff0c;我准备自学背包系统。今天先学习下UI界面设置。 一、新建场景和结点 1.新建Node2D场景&#xff0c;命名为Inventory&#xff0c;保存到Scenes目录下&#xff0c;inventory.tscn。 2.新建TextureRect子…

kivy.garden.matplotlib

matplotlib 是什么 # pip install matplotlib2.2.2 from kivy.garden.matplotlib.backend_kivyagg import FigureCanvasKivyAgg FigureCanvasKivyAgg class FigureCanvasKivyAgg(FigureCanvasKivy, FigureCanvasAgg):FigureCanvasKivyAgg class. See module documentation f…

国联易安:网络反不正当竞争,要防患于未然

据市场监管总局官网消息&#xff0c;为预防和制止网络不正当竞争&#xff0c;维护公平竞争的市场秩序&#xff0c;鼓励创新&#xff0c;保护经营者和消费者的合法权益&#xff0c;促进数字经济规范健康持续发展&#xff0c;市场监管总局近日发布《网络反不正当竞争暂行规定》&a…

微信小程序-WXS脚本

一、概述 1.WXS WXS(WeiXin Script)是小程序独有的一套脚本语言&#xff0c;结合 WXML&#xff0c;可以构建出页面的结构。 2.wxs 的应用场景 wxml中无法调用在页面的.js 中定义的函数&#xff0c;但是&#xff0c;wxml 中可以调用 wxs 中定义的函数。因此&#xff0c;小程序…

软件测试总结基础

软件测试总结基础 1. 何为软件测试 定义&#xff1a;使用技术手段验证软件是否满足需求 目的&#xff1a;减少bug&#xff0c;保证质量 2. 软件测试分类 阶段划分 单元测试&#xff0c;针对源代码进行测试集成测试&#xff0c;针对接口进行测试系统测试&#xff0c;针对功能…

Web 网页性能优化

Web 网页性能及性能优化 一、Web 性能 Web 性能是 Web 开发的一个重要方面&#xff0c;侧重于网页加载速度以及对用户输入的响应速度 通过优化网站来改善性能&#xff0c;可以在为用户提供更好的体验 网页性能既广泛又非常深入 1. 为什么性能这么重要&#xff1f; 1. 性能…