JAVA线程资源共享问题

news/2024/11/17 12:57:50/文章来源:https://www.cnblogs.com/zgf123/p/18350758

JAVA多线程共享资源问题

场景引入

这个场景是一个典型的多线程共享资源的场景,主要目的是测试和观察多个线程对共享变量 sum 进行并发操作时是否会出现线程安全问题
场景描述

共享资源:

  • 共享变量 sum,初始值为 0。
  • 多个线程同时对 sum 进行操作,一个线程负责自增操作,另一个线程负责自减操作。

线程操作:

  • 每个线程在循环中对 sum 进行 1000 次操作。
  • 自增线程每次将 sum 增加 1,自减线程每次将 sum 减少 1。

日志记录:

  • 使用 Logger 记录每次操作的线程名称、操作类型(加法或减法)以及操作后的 sum 值。

目的

  • 测试线程共享问题:通过观察 sum 的值,测试是否存在线程安全问题。如果没有同步机制,可能会出现数据不一致的情况。
  • 验证并发操作的正确性:在没有同步机制的情况下,多个线程同时操作共享变量 sum,可能会导致数据竞争和不正确的结果。

预期结果

  • 线程安全问题:由于没有使用同步机制,多个线程同时操作 sum,可能会导致数据竞争,最终 sum 的值可能不正确。
    日志输出:日志会记录每次操作的详细信息,可以通过日志观察 sum 的变化情况。
public class syncThreadDemo01 extends Thread{Logger logger = LoggerFactory.getLogger(syncThreadDemo01.class);static Integer sum = 0;// 需求: 基于sum 开启多个线程,一个线程自增,一个线程减,测试是否有线程共享问题private Boolean isAdd;private String threadName;public syncThreadDemo01(Boolean isAdd,String threadName) {this.isAdd = isAdd;this.threadName = threadName;}@Overridepublic void run() {for (int i = 0 ;i<1000;i++){if (isAdd){sum+=1;}else {sum-=1;}logger.info("线程:{}开始执行。。。。。。。。。。。,执行模式:{},输出结果:{}",threadName,isAdd?"加法":"减法",sum);}}
}
public class ThreadMainDemo {public static void main(String[] args) {
//        ThreadDemo thread = new ThreadDemo("线程1");
//        thread.start();// 测试 资源共享问题syncThreadDemo01 addThread = new syncThreadDemo01(true, "加线程");syncThreadDemo01 delThread = new syncThreadDemo01(false, "减线程");addThread.start();delThread.start();}
}

输出结果:
image

临界区

  • 一个程序运行多个线程本身是没有问题的
  • 问题出在多个线程访问共享资源
    • 多个线程读共享资源其实也没有问题
    • 在多个线程对共享资源读写操作时发生指令交错,就会出现问题
  • 一段代码块内如果存在对共享资源的多线程读写操作,称这段代码块为临界区
    例如,下面代码中的临界区
    image

synchronized

为了避免临界区的竞态条件发生,有多种手段可以达到目的。

  • 阻塞式的解决方案:synchronized,Lock
  • 非阻塞式的解决方案:原子变量

本次使用阻塞式的解决方案:synchronized,来解决上述问题,即俗称的【对象锁】,它采用互斥的方式让同一时刻至多只有一个线程能持有【对象锁】,其它线程再想获取这个【对象锁】时就会阻塞住。这样就能保证拥有锁的线程可以安全的执行临界区内的代码,不用担心线程上下文切换

image

输出结果:0

竟然说synchronizzed 是对象锁,那么我通过创建对象的方式,将对象作为形参会有什么效果,以下是静态对象和成员对象的方式
image

输出结果:不符合预期结果,产生了对资源共享的问题
分析:
由于创建线程的时候,分别创建了两次,所以在这个当中,对象锁锁的是它这个线程的本身,并没有对其他线程进行加锁。
image

竟然如此,换算成静态成员对象的方式,是否可以解决这个问题。
image
image

测试结果:符合预期,解决了多个线程 对 共享资源的问题。

变量的线程安全分析

成员变量和静态变量是否线程安全?

  • 如果它们没有共享,则线程安全
  • 如果它们被共享了,根据它们的状态是否能够改变,又分两种情况
    • 如果只有读操作,则线程安全
    • 如果有读写操作,则这段代码是临界区,需要考虑线程安全

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

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

相关文章

透过vivo的鞋子和亚马逊的椅子:探究新商业文明

有一种领先,叫微微领先。在亚马逊的会议室中,有一把永远为用户准备的椅子;在vivo,则要求不能只坐在会议室看PPT上的用户需求,而是要穿着用户的鞋子在企业奔跑。殊途同归,将“以用户导向”作为企业长期发展的基石,亚马逊和vivo真正将“让用户Happy”通过道、法、术落到了…

Neo4j 实现一个简单的CMDB管理平台

简介Neo4j是一个高性能的图形数据库管理系统,它使用图形模型来存储和查询数据。图形数据库与传统的关系型数据库不同,它们使用节点和边来表示数据实体和它们之间的关系,而不是使用表格和行,可以使用neo4j实现权限系统,知识图谱,cmdb等部署 docker run -d --name=neo4j \--…

10V45-ASEMI超低Low VF值肖特基二极管10V45

10V45-ASEMI超低Low VF值肖特基二极管10V45编辑:ll 10V45-ASEMI超低Low VF值肖特基二极管10V45 型号:10V45 品牌:ASEMI 封装:TO-277 批号:最新 恢复时间:35ns 最大平均正向电流(IF):10A 最大循环峰值反向电压(VRRM):45V 最大正向电压(VF):0.28V~0.42V 工作温度:…

方法的作用及定义

5.1 方法的作用及定义目录5.1 方法的作用及定义5.1.1 方法的作用5.1.2 方法的定义5.1.3 方法调用5.1.4 静态方法5.1.1 方法的作用 一、什么是方法呢? Java方法是语句的集合,它们在一起执行一个功能。方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被…

零基础学习人工智能—Python—Pytorch学习(三)

前言 这篇文章主要两个内容。 一,把上一篇关于requires_grad的内容补充一下。 二,介绍一下线性回归。 关闭张量计算 关闭张量计算。这个相对简单,阅读下面代码即可。 print("============关闭require_grad==============") x = torch.randn(3, requires_grad=True…

Java - IO流

(IO随用随创建,不用了就关流) 1.字节流 OutputStream(字节输出流,写出) FileOutputStreanmoff表示起始索引,len表示截取长度 Windows换行符:"\r\n" Linux:"\n" Mac:"\r" 续写:创建对象第二个参数写true字节打印流(特有方法会原样输出…

Win10无法登录到你的帐户的问题

症状登录之后,系统有个弹窗,提示无法登录到你的帐户2,桌面上原本放的东西不见了,桌面上新放的东西,重启电脑之后会丢失,不能保存 3,cmd 命令行 > echo %userprofile% 之后显示的是TEMP.000, TEMP.001这样子的临时目录问题分析尝试用过参考资料中修改注册表的方法,不…

python配置pip镜像

Python配置pip的镜像国内的网络通过pip下载软件包只有不到10k的下载速度。不仅下载的慢,还容易引发超时错误,导致下载失败。而将给pip配置国内的镜像源可以完美的解决这个问题。本文讲解了pip在windows和macos/linux的配置过程(在windows实操成功)一、 找到配置文件 1.wind…

滴滴出行:多元化出行服务创新与市场领先地位

一、产品概述 产品名称:滴滴出行 产品定位:滴滴出行是一款集多种出行方式于一体的综合出行服务平台,致力于为用户提供安全、便捷、高效的出行体验。二、功能描述 1.多样化出行服务:滴滴出行提供包括快车、专车、出租车、顺风车、代驾、公交、地铁、单车等多种出行方式,满足…

派胜OA ExpressOA 3.0 现已支持 Ubuntu 24.04 LTS

ExpressOA 3.0 跨平台,高性能,现代化的协同办公平台系统。ExpressOA 3.0 现已支持 Ubuntu 24.04 LTS - 世界上最流行的 Linux 操作系统。访问派胜OA官网:www.paioffice.com 随着 .NET 8 的推出,Ubuntu 在支持 .NET 社区方面迈出了重大的一步。 .NET 8 将在 Ubuntu 24.04 LT…

派胜OA ExpressOA 3.0 现已支持 openEuler 24.03 LTS

ExpressOA 3.0 跨平台,高性能,现代化的协同办公平台系统。ExpressOA 3.0 现已支持 openEuler 24.03 LTS - 面向数字基础设施的开源操作系统。访问派胜OA官网:https://www.paioffice.com/

OFtutorial01_inputOutput解析

OFtutorial1.C 源码解析 #include "fvCFD.H"int main(int argc, char *argv[]) {// Initialise OF case#include "setRootCase.H"// These two create the time system (instance called runTime) and fvMesh (instance called mesh).#include "creat…