什么是线程安全问题?如何确保线程安全?进来看看就明白了!!

🌈🌈🌈今天给大家分享的是:什么是线程安全,在程序中多线程并发执行的时候,是否会产生线程不安全问题,以及如何解决线程不安全问题。

清风的CSDN博客

🛩️🛩️🛩️希望我的文章能对你有所帮助,有不足的地方还请各位看官多多指教,大家一起学习交流!🛩️🛩️🛩️

✈️✈️✈️动动你们发财的小手,点点关注点点赞!在此谢过啦!哈哈哈!✈️✈️✈️

目录

 一、线程安全的概念

二、观察线程不安全 

三、解决线程不安全问题 

 3.1 线程安全问题的原因

3.2 解决方案 


 

 

 一、线程安全的概念

想给出一个线程安全的确切定义是复杂的,但我们可以这样认为: 如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该的结果,则说这个程序是线程安全的。

二、观察线程不安全 

首先,我们写一个多线程代码,一个线程负责把一个数加50000次,另一个线程也负责把这个数加50000次。(从0开始加)

class Counter{
    private int count = 0;
    public void increase(){
        count++;
    }

    public int getCount() {
        return count;
    }
}
public class Test4 {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Thread t1 = new Thread(()->{
            for (int i = 0; i < 50000; i++) {
                counter.increase();
            }
        });

        Thread t2 = new Thread(()->{
            for (int i = 0; i < 50000; i++) {
                counter.increase();
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(counter.getCount());
    }
}

程序运行结果如下:

按照我们的逻辑,希望最后得到的结果是100000,为什么会出现这么大的偏差呢?其实,这样的运行结果是由于线程不安全导致的。

事实上:上面的count++操作,在CPU指令角度看,本质上是三个操作

  • 把内存中的数据加载到CPU的寄存器中。(LOAD)
  • 把寄存器中的寄存器进行加一运行算。(ADD)
  • 把寄存器中的数据写回到内存中。

如果是单个线程执行,没有问题。但是如果是多个线程并发执行,就可能会出现错误。由于CPU调度线程的顺序是不确定的,因此这两个线程并发执行的过程中,线程1的操作可能会和线程2的操作相互影响,也就是说,这两个线程的命令的排列方式可能有很多种:

 

还有很多种情况,我就不一一列举了。

如果是按照下面的情况,那么结果是没有问题的:

执行完线程1后,继续执行线程2,结果为2,是正确结果。 

那如果是按照下面的顺序,就会出现错误:

正常结果应该是2,但是这里的最终结果是1,发生了错误,虽然是自增两次,但是由于两个线程并发执行,就可能在一定的执行顺序下,导致运算的中间结果被覆盖了。也就是发生了线程不安全。 导致结果出现问题,而且得到的这个错误值,一定小于10w。

那么,如何解决线程不安全问题呢?

三、解决线程不安全问题 

 3.1 线程安全问题的原因

  • 多个线程之间的调度顺序是随机的,操作系统使用抢占式执行的策略来调度线程。【根本原因】
  •  多个线程同时修改同一个变量,容易产生线程安全问题。
  • 进行的修改,不是原子性的。如果修改操作,能够按照原子的方式来完成,就不会出现线程安全问题。 
  • 内存可见性引起的线程安全问题。
  • 指令重排序,引起的线程安全问题。

3.2 解决方案 

 我们可以把修改操作改成“原子性”的操作,即可以进行加锁操作。相当于是把一组操作,打包成一个整体的操作。此处这里的原子,是通过锁进行“互斥”,当前线程执行的时候,其他线程无法执行。对于加锁,Java引入了一个synchornized关键字。

通过对increase方法加锁,进入方法,就会加锁;出了方法,就会解锁。 当t1加锁之后,t2也尝试进行加锁,此时t2就会阻塞等待。这样也就保证了原子性。

class Counter{
    private int count = 0;
    synchronized public void increase(){
        count++;
    }

     public int getCount() {
        return count;
    }
}
public class Test4 {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Thread t1 = new Thread(()->{
            for (int i = 0; i < 50000; i++) {
                counter.increase();
            }
        });

        Thread t2 = new Thread(()->{
            for (int i = 0; i < 50000; i++) {
                counter.increase();
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(counter.getCount());
    }
}

运行结果如下:


🌈🌈🌈好啦,今天的分享就到这里!

🛩️🛩️🛩️希望各位看官读完文章后,能够有所提升。

🎉🎉🎉创作不易,还希望各位大佬支持一下!

✈️✈️✈️点赞,你的认可是我创作的动力!

⭐⭐⭐收藏,你的青睐是我努力的方向!

✏️✏️✏️评论:你的意见是我进步的财富!

 

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

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

相关文章

HarmonyOS 后台任务管理开发指南上线!

为什么要使用后台任务&#xff1f;开发过程中如何选择合适的后台任务&#xff1f;后台任务申请时存在哪些约束与限制&#xff1f; 针对开发者使用后台任务中的疑问&#xff0c;我们上线了概念更明确、逻辑结构更清晰的后台任务开发指南&#xff0c;包含具体的使用场景、详细的开…

“2024年国考公共科目”趣谈

黄金的熔点仅为1064.43C&#xff0c;不锈钢、耐高温钢所需的冶炼温度也仅需2000℃以上&#xff0c;因此与正在进行中的“2024年国考公共科目笔试”的“报名人数首破300万&#xff0c;平均约77人竞争一岗位”相比&#xff0c;炼金炼钢温度全都败落下风。 网络图片 其中宁夏的一…

Docker安装Elasticsearch以及ik分词器

Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎&#xff0c;能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心&#xff0c;Elasticsearch 会集中存储您的数据&#xff0c;让您飞快完成搜索&#xff0c;微调相关性&#xff0c;进行强大的分析&#xff…

【导航控制器的基本使用 Objective-C语言】

一、导航控制器的基本使用 1.那接下来呢,我们就要讲解这个重中之重了啊,导航控制器,大家一定要注意听,那首先呢,我们先来看ppt,引导一下, 导航控制器.pptx,打开, 那接下来呢,我们就要学习这个多控制器的管理了, 里面的第一个内容,叫做导航控制器, 那今天呢,我们…

21款奔驰GLC300L升级HUD抬头显示 平视仪表信息

说起HUD抬头显示这个配置&#xff0c;最初是用在战斗机上的&#xff0c;它可以让战斗机驾驶员读取飞机的各种信息和状态&#xff0c;而无需移动头部&#xff0c;这样就能够有效的提高效率。但随着汽车技术的进步HUD这种配置也逐渐下放到民用车上。发展到今&#xff0c;车上的抬…

API接口的接入|数据服务化在京东的实践

导读 本次分享的主题为数据服务化在京东的实践&#xff0c;主要包含三个模块&#xff1a;数据服务化的缘起、成长、如何将系统做得更好。 01 缘起&#xff1a;数据服务化从 0 到 1 1. 缘起 京东数据智能部负责维护数据资产和对外提供数据服务&#xff0c;很多业务方要求我们…

vue+jsonp编写可导出html的模版,可通过外部改json动态更新页面内容

效果 导出后文件结果如图所示&#xff0c;点击Index.html即可查看页面&#xff0c;页面所有数据由report.json控制&#xff0c;修改report.json内容即可改变index.html展示内容 具体实现 1. 编写数据存储的json文件 在index.html所在的public页面新建report.json文件&#xff…

为什么单片机课要学 51+ 汇编,而不直接学 STM32?

为什么单片机课要学 51 汇编&#xff0c;而不直接学 STM32&#xff1f; 为什么单片机课要学 51 汇编&#xff0c;而不直接学 STM32&#xff1f; 这个没有规定一定要学那个51 汇编。 只能说C51更为简单、控制和理解硬件更为容易上手。 你可以在学习C51的时候&#xff0c;可以很容…

低功耗蓝牙模块在工业自动化中的创新应用

随着工业自动化的不断发展&#xff0c;低功耗蓝牙技术在工业环境中的应用正逐渐引起广泛关注。本文将深入探讨低功耗蓝牙模块在工业自动化中的创新应用&#xff0c;着重介绍其在传感器网络、设备监测和生产优化等方面的优势&#xff0c;以推动工业自动化向更高效、可靠、智能化…

网站优化进阶指南:如何用Python爬虫进行网站结构优化

前段时间一个做网络优化的朋友找我&#xff0c;问我能不能通过爬虫的手段对他们自己的网络进行优化。这个看着着实比较新颖&#xff0c;对于从事爬虫行业的程序员来说&#xff0c;很有挑战性&#xff0c;值得尝试尝试。 说白了使用爬虫进行网站优化需要对网站的结构、内容、链…

华为与夏普达成全球专利交叉许可协议 / 阿里巴巴发布千亿级参数的自研夸克大模型|魔法半周报

我有魔法✨为你劈开信息大海❗ 高效获取AIGC的热门事件&#x1f525;&#xff0c;更新AIGC的最新动态&#xff0c;生成相应的魔法简报&#xff0c;节省阅读时间&#x1f47b; &#x1f525;资讯预览 华为与夏普达成全球专利交叉许可协议&#xff0c;5G领域领先地位再次得到认可…

Docker的基本概念和优势,以及在应用程序开发中的实际应用

文章目录 概要 基本概念 容器 (Container): 镜像 (Image): Dockerfile: 仓库 (Repository): 容器编排 (Orchestration): Docker Compose: Docker Daemon 和 Docker Client: 网络 (Network): 数据卷 (Volume): 主要优势 应用场景 小结 概要 Docker 是一种容器化平台&#xff0c;…

大数据之 Hadoop

hadoop主要解决&#xff1a;海量数据的存储和海量数据的分析计算 hadoop发展历史 Google是hadoop的思想之源&#xff08;Google在大数据方面的三篇论文&#xff09; 2006年3月&#xff0c;Map-reduce和Nutch Distributed File System(NDFS)分别被纳入到Hadoop项目&#xff0c…

webshell之字节码免杀

字节码生成 javac生成字节码 这种方式简单的说就是用ideal将java文件编程成class文件&#xff0c;然后将class读取出来用base64编码即可&#xff0c;这种方式比较方便简单&#xff0c;不需要会使用ASM&#xff0c;javassist等字节码框架。 Shell.java javassist生成字节码 j…

新手老师如何管理班级的日常工作

作为一名新手老师&#xff0c;管理班级的日常工作可能会是一项挑战&#xff0c;但以下是一些可能有用的建议&#xff1a; 建立良好的班级文化 班级文化是班级氛围的重要组成部分&#xff0c;对于学生的学习和成长具有重要影响。作为老师&#xff0c;要积极营造一种积极向上、团…

冒泡排序以及改进方案

冒泡排序以及改进方案 介绍&#xff1a; 冒泡排序属于一种典型的交换排序&#xff08;两两比较&#xff09;。冒泡排序就像是把一杯子里的气泡一个个往上冒一样。它不断比较相邻的元素&#xff0c;如果顺序不对就像水泡一样交换它们的位置&#xff0c;直到整个序列像水泡一样…

viple模拟器使用(四):unity模拟器中实现沿右墙迷宫算法

沿右墙迷宫算法 引导 线控模拟可以使得通过用户手动操作&#xff0c;实现机器人在模拟环境下在迷宫中行走&#xff08;即&#xff1a;运动&#xff09;&#xff0c;算法可以使得机器人按照一定的策略自动行走&#xff0c;沿右墙迷宫算法就是其中的一种策略。 目的 运行程序后&…

C语言--求x的y次方【详细解释+代码优化】

一.利用库函数pow&#x1f357; pow函数的原型为&#xff1a; double pow(double base, double exponent); base为底数&#xff0c;exponent为指数&#xff0c;传入两个参数&#xff0c;返回值是计算的结果。需要引用头文件#include<math,h>. //方法一&#xff1a;利…

快捷键被占用了,这能忍吗?赶紧使用 OpenArk 找出元凶并干掉它!!!

文章目录 一、 问题&#xff1a;快捷键被占用了导致影响工作效率二、OpenArk 2.1 OpenArk简介 功能发布官方链接 2.2 下载OpenArk2.3 运行OpenArk2.4 被占用的热键元凶到底是谁&#xff1f; 三、总结 一、 问题&#xff1a;快捷键被占用了导致影响工作效率 你是否遇到过&#x…

教师如何备课,上好一堂课

作为一名教师&#xff0c;备课是上好一堂课的关键。备课不仅仅是准备教材和教具&#xff0c;更是制定教学计划、设计教学方法、预测学生学习效果的重要环节。接下来我分享几点备课和上课的心得。 深入理解教学大纲 教学大纲是备课的指导性文件&#xff0c;只有深入理解教学大纲…