系列二、为什么要使用ThreadLocal?

一、为什么要使用ThreadLocal?

1.1、概述

        并发场景下,会存在多个线程同时修改一个共享变量的场景,这就有可能会出现线程安全的问题。为了解决线程安全问题,可以用加锁的方式,比如对核心代码使用synchronized或者Lock进行加锁,从而起到线程隔离的效果。但是加锁的方式,在高并发下会导致系统变慢,加锁示意图如下:

        还有另外一种方案,就是使用空间换时间的方式,即:使用ThreadLocal,使用ThreadLocal访问共享变量时,会在每个线程本地保存一份共享变量的副本。多线程对共享变量修改时,实际上每个线程操作的是自己的变量副本,从而保证线程安全。示意图如下:

1.2、线程不安全案例

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/21 11:50
 * @Description: 需求:线程隔离(线程不安全案例代码)
 */
public class SetAndGetThreadVariableDemo1MainApp {
    /**
     * 共享变量
     */
    private String content;
    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public static void main(String[] args) {
        SetAndGetThreadVariableDemo1MainApp app = new SetAndGetThreadVariableDemo1MainApp();
        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                try {
                    app.setContent(Thread.currentThread().getName() + "的数据");
                    System.out.println("=======================");
                    System.out.println(Thread.currentThread().getName() + "===>" + app.getContent());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, "线程" + i).start();
        }
    }

}

1.3、线程不安全案例(ThreadLocal解决)

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/21 11:50
 * @Description: 需求:线程隔离(ThreadLocal实现)
 * 在多线程并发的场景下,每个线程中的变量都是互相独立的
 *      线程A:    设置(变量1)     获取(变量1)
 *      线程B:    设置(变量2)     获取(变量2)
 *
 * ThreadLocal:
 *      1、set():将变量绑定到当前线程中
 *      2、get():获取当前线程绑定的变量
 */
public class SetAndGetThreadVariableDemo2MainApp {

    private String content;
    ThreadLocal<String> threadLocal = new ThreadLocal<>();

    public String getContent() {
        return threadLocal.get();
    }

    public void setContent(String content) {
        threadLocal.set(content);
    }

    public static void main(String[] args) {
        SetAndGetThreadVariableDemo2MainApp app = new SetAndGetThreadVariableDemo2MainApp();
        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                try {
                    app.setContent(Thread.currentThread().getName() + "的数据");
                    System.out.println("=======================");
                    System.out.println(Thread.currentThread().getName() + "===>" + app.getContent());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, "线程" + i).start();
        }
    }

}

1.4、线程不安全案例(synchronized解决)

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/21 11:50
 * @Description: 需求:线程隔离(synchronized实现)
 *
 */
public class SetAndGetThreadVariableDemo3MainApp {

    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public static void main(String[] args) {
        SetAndGetThreadVariableDemo3MainApp app = new SetAndGetThreadVariableDemo3MainApp();
        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                try {
                    synchronized (SetAndGetThreadVariableDemo3MainApp.class) {
                        app.setContent(Thread.currentThread().getName() + "的数据");
                        System.out.println("=======================");
                        System.out.println(Thread.currentThread().getName() + "===>" + app.getContent());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, "线程" + i).start();
        }
    }

}

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

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

相关文章

排序算法--插入排序

实现逻辑 ① 从第一个元素开始&#xff0c;该元素可以认为已经被排序 ② 取出下一个元素&#xff0c;在已经排序的元素序列中从后向前扫描 ③如果该元素&#xff08;已排序&#xff09;大于新元素&#xff0c;将该元素移到下一位置 ④ 重复步骤③&#xff0c;直到找到已排序的元…

最新红盟云卡个人自动发卡开源系统源码+全开源无加密+虚拟商品在线售卖平台

源码简介&#xff1a; 最新红盟云卡个人自动发卡开源系统源码全开源无加密虚拟商品在线售卖平台&#xff0c;支持多个接口的个人免签功能。 红盟云卡系统是一款基于PHP和MySQL开发的虚拟商品在线售卖平台。它具备美观且功能丰富的发卡网站特性&#xff0c;并可与社区进行无缝…

数独·12中解法·anroid 数独小游戏·休闲益智小游戏

标题数独12中解法anroid 数独小游戏休闲益智小游戏&#xff08;继续更新中……&#xff09; 一款经典数独训练app 资源下载 &#xff08;0积分&#xff09;https://download.csdn.net/download/qq_38355313/88544810 —— —— 数独&#xff08;sh d&#xff09;是源自18世纪…

重磅!TikTok Shop将以新方式重启印尼业务

据报道&#xff0c;TikTok将通过与印尼电商平台合作的方式重启电商业务。 据悉&#xff0c;印尼合作社和中小企业部就TikTok Shop将在印尼重新开业的消息发表了讲话。合作社和中小企业部Temmy Satya Permana证实TikTok Shop将在印尼重新开业的消息。他表示&#xff0c;TikTok …

酒店预订订房小程序源码系统+多酒店入驻 功能齐全 附带完整的搭建教程

随着互联网的快速发展&#xff0c;越来越多的人选择通过在线预订平台预订酒店。为了满足这一需求&#xff0c;我们开发了这个酒店预订订房小程序源码系统。该系统基于先进的云计算技术和大数据分析&#xff0c;旨在为用户提供更加便捷、智能的酒店预订服务。 以下是部分代码示…

java+springboot+bootstrap校园闲置物品拍卖交易平台_ngad7-

根据日常实际需要&#xff0c;一方面需要在系统中实现基础信息的管理&#xff0c;同时还需要结合实际情况的需要&#xff0c;提供校园闲置物品交易管理功能&#xff0c;方便校园闲置物品交易管理工作的展开&#xff0c;综合考虑&#xff0c;本套系统应该满足如下要求&#xff1…

【C++】二叉搜索树

二叉搜索树 1.二叉搜索树概念2.二叉搜索的实现2.1结点2.1基本框架2.2插入2.3查找2.4删除2.5打印 3.二叉搜索树递归实现3.1查找3.2插入3.3删除 4.二叉搜索树默认成员函数4.1构造4.2析构4.3拷贝构造4.4赋值重载 6.二叉搜索树的应用6.1K模型6.2KV模型 7.二叉搜索树的性能分析 喜欢…

Apache服务Rwrite功能使用

Rewrite也称为规则重写&#xff0c;主要功能是实现浏览器访问时&#xff0c;URL的跳转。其正则表达式是基于Perl语言。要使用rewrite功能&#xff0c;Apache服务器需要添加rewrite模块。如果使用源码编译安装&#xff0c;–enable-rewrite。有了rewrite模块后&#xff0c;需要在…

Rust生态系统:探索常用的库和框架

大家好&#xff01;我是lincyang。 今天我们来探索Rust的生态系统&#xff0c;特别是其中的一些常用库和框架。 Rust生态系统虽然相比于一些更成熟的语言还在成长阶段&#xff0c;但已经有很多强大的工具和库支持各种应用的开发。 常用的Rust库和框架 Serde&#xff1a;一个…

Redis篇---第十三篇

系列文章目录 文章目录 系列文章目录前言一、redis的过期策略以及内存淘汰机制二、Redis 为什么是单线程的三、Redis 常见性能问题和解决方案?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看…

绝地求生:想玩以前的老地图

小编是22年8月左右开始玩的&#xff0c;更早以前跟同学偶尔玩过几次&#xff0c;所以萨诺2.0玩过&#xff0c;不过那时候菜的还不如人机&#xff0c;死了都看不到人在哪&#xff0c;所以对地图没啥印象&#xff0c;比较有印象的是地图色调变得很黄昏。 自闭城 遗迹 这是迪厅&am…

机器人算法—ROS TF坐标变换

1.TF基本概念 &#xff08;1&#xff09;什么是TF&#xff1f; TF是Transformations Frames的缩写。在ROS中&#xff0c;是一个工具包&#xff0c;提供了坐标转换等方面的功能。 tf工具包&#xff0c;底层实现采用的是一种树状数据结构&#xff0c;根据时间缓冲并维护多个参考…

【云栖 2023】姜伟华:Hologres Serverless 之路——揭秘弹性计算组

云布道师 本文根据 2023 云栖大会演讲实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a;姜伟华 | 阿里云计算平台事业部资深技术专家、阿里云实时数仓 Hologres 研发负责人 演讲主题&#xff1a;Hologres Serverless 之路——揭秘弹性计算组 实时化成为…

基于SSM 离退休管理平台-计算机毕设 附源码 52629

ssm离退休管理平台 摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用SSM技术和mysql数据库来完成对系统的…

vatee万腾科技先锋之选:vatee创新力驱动着未来发展

在科技潮流的浩荡前行中&#xff0c;Vatee万腾崭新的科技先锋之选正以强大的创新力引领着未来的发展。Vatee万腾凭借其前瞻性的技术理念和卓越的创新实践&#xff0c;成为业界的引领者&#xff0c;为整个科技行业树立了标杆。 Vatee万腾不仅仅是一家科技公司&#xff0c;更是一…

django ModelSerializer自定义显示字段

文章目录 前言一、问题二、解决 前言 最近在复习django的时候&#xff0c;发现了一个有趣的问题&#xff0c;解决了之后特意记录下来&#xff0c;以供以后参考。 一、问题 相信大家使用django的时候&#xff0c;被其DRF的强大功能所折服&#xff0c;因为它能通过简单的代码就…

一、防火墙-安全区域

学习防火墙之前&#xff0c;对路由交换应要有一定的认识 1、什么是防火墙2、防火墙的发展史3、安全区域3.1.接口、网络和安全区域的关系3.2.报文在安全区域之间流动方向3.3.安全区域的配置安全区域小实验 3.4.状态检测和会话机制3.4.1.状态检测3.4.2.会话 3.5.状态检测和会话机…

opencv-图像梯度

目标 • 图像梯度&#xff0c;图像边界等 • 使用到的函数有&#xff1a;cv2.Sobel()&#xff0c;cv2.Schar()&#xff0c;cv2.Laplacian() 等 原理 梯度简单来说就是求导。 OpenCV 提供了三种不同的梯度滤波器&#xff0c;或者说高通滤波器&#xff1a;Sobel&#xff0c;Schar…

在Linux服务器中查找mysql的配置文件并修改其内容并保存,清空mysql8.0以上默认开启SSL的配置,防止odbc无法连接的问题

------每个命令输完记得按【enter】回车键------- 1、查找mysql的配置文件命令-mysql的配置文件默认名是my.cnf&#xff1a; find / -name my.cnf 2、查看显示的配置文件内容&#xff1a; cat /etc/my.cnf 3、修改配置文件的内容&#xff1a; 使用vi 或vim 命令 vi /etc…

分享一些简单的英语问候语

昨天和一个朋友聊天&#xff0c;他问我最近有没有某个国家的客户&#xff1f;我说只有一两个&#xff0c;都已经好久没有联系了&#xff0c;上一次问候还是在九月份。他说从十月底开始就收到很多来自当地的询盘&#xff0c;你不妨问下客户最近是否有新的需求&#xff1f; 于是…