多线程 -- 线程安全问题(3)

news2025/1/9 16:34:50

本篇重点: 总结线程安全问题的原因以及解决办法

目录

    • synchronized 加锁关键字
        • join 和 synchronized 的区别
        • volatile 关键字

在上一篇中我们介绍了Thread类的基本使用方法, 本篇将会介绍有关于线程的安全问题

线程不安全的原因:

  1. 抢占式执行(罪魁祸首, 万恶之源)

  2. 多个线程修改同一个变量

    一个线程修改同一个变量 => 安全
    多个线程读取同一个变量 => 安全
    多个线程修改不同变量 => 安全
    
  3. 修改操作并不是原子的

    像是++操作就不是原子操作
    
  4. 内存可见性, 引起的线程不安全

  5. 指令重排序, 引起的线程不安全

线程不安全代码案例
使用两个线程来累加 count 的值, 每个线程循环 1w 次,累加变量 count 的值,count 默认值为 0,注意线程安全问题。

class Counter{
    private int count;
    public void add() {
            count++;
    }

    public int getCount() {
        return count;
    }
}
public class ThreadDemo13 {

    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();

        // 搞两个线程各自自增5w次看结果
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                counter.add();
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                counter.add();
            }
        });
        t1.start();
        t2.start();

        // 等待两个线程执行结束, 然后看结果
        t1.join();
        t2.join();
        System.out.println(counter.getCount());

    }
}

因为count++操作并不是原子性的所以线程并不安全

如何解决以上线程不安全问题???

synchronized 加锁关键字

加锁!!!

对count++ 进行加锁

此处使用代码块的方式来表示

进入synchronized 修饰的代码块的时候, 就会触发加锁 
出了synchronized 代码块, 就会触发解锁
    public void add() {
            synchronized (this){// this 指向的是count对象
                count++;
            }
    }

也可以在方法前加上synchronized关键字

    synchronized public void add() {
    	count++;
    }

join 和 synchronized 的区别

join只是让两个线程完整的进行串行
加锁, 两个线程的某个小部分串行了, 大部分都是并发的!!!

volatile 关键字

Volatile关键字的作用主要有如下两个:
1.线程的可见性:当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。
2. 顺序一致性:禁止指令重排序。

被volatile 优化的关键字,会禁止编译器进行优化
当循环次数下降了, load操作, 不再是负担了, 编译器就没必要优化了
指令重排序, 也是编译器优化的策略

public class ThreadDemo14 {
    volatile public static int flag = 0;

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            while (flag == 0) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("循环结束, t1线程结束");
        });
        Thread t2 = new Thread(() -> {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入一个整数: ");
            flag = scanner.nextInt();
        });
        t1.start();
        t2.start();
    }
}

在这里插入图片描述

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

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

相关文章

搜索推荐系统[10]项目实战系列Z5:汽车说明书跨模态智能问答系统,针对汽车说明书(可自定义文档)进行自动问答,采用了OCR、RocketQA等技术

搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排)、系统架构、常见问题、算法项目实战总结、技术细节以及项目实战(含码源) 专栏详细介绍:搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排)、系统架构、常见问题、算法项目实战总结、技术…

小程序之页面通信派发通知

文章目录 1. 介绍小程序页面通信的概念解释小程序页面通信的意义和必要性介绍小程序页面通信的方法 2. 小程序页面通信的实现示例通过事件传递数据实现页面之间通信通过全局变量实现页面之间通信 3. 实现小程序页面之间的消息通知介绍小程序发布订阅模式的概念使用事件订阅-发布…

网络通信IO模型-BIO

承接上文网络通信IO模型上 BIO的Java代码 服务端创建一个ServerSocket&#xff0c;绑定了端口号8090&#xff0c;目的是让客户端和服务端建立连接后进行通信&#xff0c;然后进入死循环&#xff0c;死循环里面会调用server.accept得到一个socket客户端&#xff0c;打印客户端的…

【PyQt5】指示灯显示

【PyQt5】指示灯显示 1、背景2、代码示例3、QtDesigner绘制 1、背景 利用Qt5写工业控制软件交互界面的时候&#xff0c;经常需要在界面上有指示灯功能。 例如下面的明暗表示串行端口的连接和断开。 我们本质是用Qt5的label文本标签来实现的&#xff0c;即通过设置标签的样式表…

115.删除有序数组中的重复项 removeDuplicatesFromSortedArray

文章目录 题目描述解题思路代码详解运行截图 题目描述 题目链接 给你一个 升序排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元…

C# | 凸包算法之Jarvis,寻找一组点的边界/轮廓

C#实现凸包算法之Jarvis 文章目录 C#实现凸包算法之Jarvis前言示例代码实现思路测试结果结束语 前言 这篇关于凸包算法的文章&#xff0c;本文使用C#和Jarvis算法来实现凸包算法。 首先消除两个最基本的问题&#xff1a; 什么是凸包呢&#xff1f; 凸包是一个包围一组点的凸多…

驱动LSM6DS3TR-C实现高效运动检测与数据采集(1)----获取ID

概述 本文将介绍如何驱动和利用LSM6DS3TR-C传感器&#xff0c;实现精确的运动感应功能。LSM6DS3TR-C是一款先进的6轴惯性测量单元&#xff08;IMU&#xff09;&#xff0c;集成了三轴加速度计和三轴陀螺仪&#xff0c;可用于测量和检测设备的加速度、姿态和运动。 本文将提供L…

车载软件架构 —— 闲聊几句AUTOSAR OS(二)

我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 在最艰难的时候,自己就别去幻想太远的将来,只要鼓励自己过好今天就行了! 这世间有太多的猝不及防,有些东西根本不配占有自己的情绪,人生就是一场体验,…

牛客HJ43迷宫问题 - 创建智能体通过策略自己找路

文章目录 问题描述思路代码C 问题描述 描述 定义一个二维数组 N*M &#xff0c;如 5 5 数组下所示&#xff1a; int maze[5][5] { 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫&#xff0c;其中的1表示墙壁&#xff0…

SPA首屏加载速度慢的怎么解决?

SPA首屏加载速度慢的怎么解决&#xff1f; 加载慢的原因 网络延时问题资源文件体积是否过大资源是否重复发送请求去加载了加载脚本的时候&#xff0c;渲染内容堵塞了 解决方案 1.减小入口文件体积 常用的手段是路由懒加载&#xff0c;把不同路由对应的组件分割成不同的代码…

如何在华为OD机试中获得满分?Java实现【水仙花数】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述4. Java算法源码5. 测试6.解题思路1. 题目描述 所谓水仙花数,是指一个…

LeetCode高频算法刷题记录10

文章目录 1. 旋转图像【中等】1.1 题目描述1.2 解题思路1.3 代码实现 2. 组合总和【中等】2.1 题目描述2.2 解题思路2.3 代码实现 3. 回文链表【简单】3.1 题目描述3.2 解题思路3.3 代码实现 4. 字符串解码【中等】4.1 题目描述4.2 解题思路4.3 代码实现 5. 多数元素【简单】5.…

高压功率放大器ATA4014VS高压功率放大器HSA42014

高压功率放大器ATA4014VS高压功率放大器HSA42014 一、企业背景&#xff1a; Aigtek是一家来自中国的专业从事测量仪器研发、生产和销售的高科技企业。公司主要研发和生产功率放大器、功率放大器模块、功率信号源、计量校准源等产品。核心团队主要是来自西安交通大学及西北工业大…

ERP系统介绍

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、ERP系统概述&#xff1f;1.什么是ERP2.主流ERP系统介绍3.用友ERP4.部署用友ERP畅捷通T6软件系统环境要求4.用友ERP畅捷通T6软件用户管理4.用友ERP畅捷通T6软…

简单的UDP网络程序

目录 准备工作 makefile udpServer.hpp udpServer.cc 细节1 服务端部署 创建套接字 接口认识1 socket 协议家族 绑定套接字 认识接口2 bind sockaddr_in结构体类型 细节2 bzero inet_addr 服务器启动(初启动) udpServer.hpp udpServer.cc 细节3 本地回环通…

跑通NeRF-SLAM代码记录

前言 Install 原文章github链接 下载代码 git clone https://github.com/ToniRV/NeRF-SLAM.git --recurse-submodules git submodule update --init --recursive因为有相关依赖&#xff0c;所以尽量使用命令下载代码。 2. 新建nerf-slam环境&#xff0c;github上也没提到p…

从sftp下载大文件到浏览器

从sftp下载大文件到浏览器 问题方案相关依赖包相关代码片段&#xff08;后端&#xff09;文件信息缓存工具类-FileChunkCache文件信息对象-FileDetailsftp传输进度监控-FileProgressMonitor切片工具类-ChunkService文件下载服务-AsyncDownloadService 问题 近期遇到直接使用sf…

Dubbo与SpringBoot整合

1.注意starter版本适配 2.服务提供者 创建Maven项目 boot-user-service-provider 服务提供者 2.1.通用模块依旧照用 2.2.POM <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</a…

如何在华为OD机试中获得满分?Java实现【IPv4地址转换成整数】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述4. Java算法源码5. 测试6.解题思路1. 题目描述 存在一种虚拟 IPv4<

本地创建的项目托管到git

本地创建的项目托管到git 这里的情况是本地先通过命令在电脑上指定文件夹创建好项目后&#xff0c;需要托管到git上&#xff0c;这里以gitee为例 打开gitee&#xff0c;登录滑动到右上方&#xff0b;&#xff0c;点击新建仓库&#xff0c;跳转到新建仓库页面 填写仓库信息&am…