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;
        }

        @Override
        public 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 变量可能会增加线程间切换的开销,需要权衡使用场景和性能影响。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTB 靶场 Mailing 未完待续

访问网页 在/etc/hosts 添加ip和域名 hosts 文件包含ip地址与主机名之间的映射&#xff0c;还包括主机的别名。 Linux系统所有程序查询/etc/hosts文件解析对主机名或者域名的IP地址。没有找到就需要使用DNS服务器解释域名。 DNS原理 1 输入域名&#xff0c;在本地缓存服务…

【工具】Vmware17 安装mac(13.6.7)虚拟机

目录 0.简介 1.环境 2.详细步骤 2.1下载mac镜像&#xff08;可以选择你所需要的&#xff09; 2.2 VMware安装 1&#xff09;创建新的虚拟机 2&#xff09;选择【典型】&#xff0c;点击下一步 3&#xff09;选择【安装程序光盘映像文件】&#xff0c;点击浏览&#xff…

公派/自费访问学者申请出国访学的常见问题解答(下)

06、学术背景和研究成果要求&#xff1f; 访学是面向学术单位和企事业单位开放的。 针对学术单位&#xff0c;比如高校与科研院所&#xff0c;学科内涉及的论文发表&#xff0c;课题研究&#xff0c;专利&#xff0c;著作&#xff0c;含金量较高的奖项等背景都是国外比较看重…

rollup.js(入门篇)

前沿 Rollup 是一个用于 JavaScript 的模块打包工具&#xff0c;它将小的代码片段编译成更大、更复杂的代码&#xff0c;例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式&#xff0c;而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许…

亚马逊云,不想失去云计算的“铁王座”

文&#xff5c;白 鸽 编&#xff5c;王一粟 “生成式AI时代的黎明已经来临。” 亚马逊全球副总裁、亚马逊云科技大中华区总裁储瑞松在2024年亚马逊云中国科技峰会上&#xff0c;再次强调了生成式AI对于亚马逊云科技和整个行业的重要性。 事实上&#xff0c;从去年开始&a…

JVM 运行流程

JVM 是 Java 运行的基础&#xff0c;也是实现一次编译到处执行的关键&#xff0c;那么 JVM 是如何执行的呢&#xff1f; JVM 执行流程 程序在执行之前先要把java代码转换成字节码&#xff08;class 文件&#xff09;&#xff0c; JVM 首先需要把字节码通过一定的 方式 类加…

独立游戏之路 -- 上架TapTap步骤和注意事项

个人开发者游戏上架TapTap上架步骤和注意事项 一、TapTap 介绍二、独立游戏上架 TapTap 的步骤2.1 创建游戏2.2 提交游戏审核2.3 TapTap 平台上发布。 三、注意事项3.1 关于备案3.2 遵守 TapTap 的规定3.3 保证游戏质量 四、常见问题4.1 隐私政策问题4.2 先发布还是先优化&…

Mybatis02-CRUD操作及配置解析

1、CRUD 1.namespace namespace中的包名要和Dao/Mapper 接口的包名一致&#xff01; 1个Dao接口类对应1个mapper&#xff0c;也对应1个namespace&#xff0c; 1个Dao接口中的方法对应1个namespace中一个SQL语句 2.CRUD id&#xff1a;对应的namespace接口中的方法名resul…

【读书笔记】曼陀罗思考法

目录 1 起源2 路径示例——人生规划设计 3 分类3.1 扩展型“扩展型”曼陀罗——使用方法 3.2 围绕型 4 注意事项 1 起源 曼陀罗在梵文中意味着“圣地”&#xff0c;象征着宇宙的秩序和内心的神圣结构。 “曼陀罗思考法”&#xff0c;是由日本学者今泉浩晃发明的方法&#xff…

从零开始实现自己的串口调试助手(6) -换行问题

解决接收的自动换行 自动换行原因 --> 我们以append发送 会自动换行 换个api 即可 --> 我们换成 insertPlainText 添加自动换行 实现添加新行 修改的函数代码: on_btnSendContext_clicked void Widget::on_btnSendContext_clicked() {// const char * sendData ui->…

C#WPF数字大屏项目实战10--不良指标分页

1、区域划分 2、区域布局 3、视图模型 4、控件绑定 5、运行效果 走过路过&#xff0c;不要错过&#xff0c;欢迎点赞&#xff0c;收藏&#xff0c;转载&#xff0c;复制&#xff0c;抄袭&#xff0c;留言&#xff0c;动动你的金手指&#xff0c;财务自由

java常见api :Math System

一. Math类 1.定义在那个包 java.lang包下 2.作用 (1)是一个帮助我们用于进行数学计算的工具类 (2)私有化构造方法,所有的方法都是静态的 3.常用的方法 &#xff08;1&#xff09;获取绝对值 System.out.println(Math.abs(-88)); 取值范围&#xff1a; -2147483648到21…

工信部《工业和信息化领域数据安全风险评估实施细则(试行)》实行,行云管家数据产品助力企业数据安全

2024年6月1日&#xff0c;工信部颁布的《工业和信息化领域数据安全风险评估实施细则&#xff08;试行&#xff09;》&#xff08;以下简称《细则》&#xff09;开始实行&#xff0c;旨在引导工业和信息化领域数据处理者规范开展数据安全风险评估工作&#xff0c;提升数据安全管…

精打细算:可燃气体报警器检验收费的合理规划与管理

随着工业化的快速发展&#xff0c;可燃气体报警器已经成为各类工业场所不可或缺的安全设备。 它的主要功能是在可燃气体浓度超标时发出警报&#xff0c;有效预防和减少火灾、爆炸等安全事故的发生。 然而&#xff0c;为了确保报警器能够持续、准确地发挥作用&#xff0c;定期…

【Python】 Python单元测试入门:运行典型的测试目录结构

基本原理 单元测试是软件开发中不可或缺的一部分&#xff0c;它帮助开发者确保每个单元&#xff08;通常是函数或类方法&#xff09;在修改后仍然按预期工作。Python 的 unittest 模块提供了一套丰富的工具来帮助开发者编写和运行单元测试。 在 Python 项目中&#xff0c;一个…

godot的安装和使用 1

今天是第一节&#xff0c;因此呢先做godot的安装&#xff0c;其实很简单 godot官网&#xff1a;https://godotengine.org/ 进入官网&#xff0c; 安装好之后呢&#xff0c;会有两个文件 打开第一个就是可视化界面的&#xff0c;进入后是这个样子 说明安装成功了

try…except…finally语句

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 完整的异常处理语句应该包含finally代码块&#xff0c;通常情况下&#xff0c;无论程序中有无异常产生&#xff0c;finally代码块中的代码都会被执行…

实战:一款唯美的个人主页-home2.0-2024.6.4(测试成功)

目录 文章目录 目录实验软件前提条件效果说明1、背景2、配置1、克隆代码库2、配置并构建镜像3、部署测试方案1&#xff1a;从docker容器拷贝生成的静态文件放到网站/目录方案2&#xff1a;启动容器&#xff0c;nginx里配置反向代理&#xff08;推荐&#xff09; 4、访问 3、总结…

JSON 数据格式化方法

文章目录 数据介绍IDE 或脚本格式化在线工具网址总结 数据介绍 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;它基于JavaScript 编程语言的一个子集。尽管它起源于 JavaScript&#xff0c;但 JSON 已经成为了一个完全独立于…

杨校老师项目之SpringBoot整合Vue与微信小程序的外卖订餐系统

1.获取代码&#xff1a; 有偿获取&#xff1a;mryang511688 2.技术栈 SpringBoot MySQL mybatis Redis 微信小程序 摘 要 随着国内外卖行业的蓬勃发展&#xff0c;外卖平台间的竞争影响了许多餐饮企业。许多餐饮企业面临着第三方外卖平台抽佣高、营销策略受限等问题&am…