Java多线程中条件判断为啥要用while判断

2023-11-18

Java多线程中条件判断

一、使用if判断造成的线程虚假唤醒问题

​ 我们在使用线程时,进行条件判断时,往往会先考虑使用if进行判断,在线程进行等待时就会出现不确定的结果。先来看看两个线程下的操作。

/**
	多线程编程模式
	1、高聚低合前提下,线程操作资源类
	2、判断/干活/通知
	3、防止虚假唤醒
**/
class A {
    private int nums = 0;

    public synchronized void increment() throws InterruptedException {
        //等待条件
        if (nums != 0) {
            //等待
            this.wait();
        }
        nums++;
        System.out.println(Thread.currentThread().getName() + "->=" + nums);
        //通知其它线程,我+1完成了
        this.notifyAll();
    }

    public synchronized void decrement() throws InterruptedException {
        //等待条件
        if (nums == 0) {
            //等待
            this.wait();
        }
        nums--;
        System.out.println(Thread.currentThread().getName() + "->=" + nums);
        //通知其它线程,我-1完成了
        this.notifyAll();
    }
}

public class Test2 {
    public static void main(String[] args) {
        A a = new A();
        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    a.increment();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "A").start();

        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    a.decrement();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "B").start();
    }
}

对于两个线程(一个生产,一个消费)时,可以保证正确结果,原因如下图解析:

在这里插入图片描述

从上图分析可以看到,每次有线程进行生产或者消费时,另一个线程会进入wait状态,直到生产或者消费完成时通知才进行后续操作。所以,对于两个线程时,使用if进行条件判断可以保证正确结果。

二、为啥要使用while来进行条件判定

使用if判断对于多个线程操作时,结果就不一定了,以四个线程为例,结果如下:

在这里插入图片描述

从结果可以得知,nums的结果出现了大于1

原因分析:

​ 在Java程序中,Java语言不能真正的去操纵线程执行,线程实际运行是交由c++去处理的,这是和cpu的时间片算法有关,和操作系统有关。分析见下:

//生产者代码
public synchronized void increment() throws InterruptedException {
  //生产等待条件
  if (nums != 0) {
   //等待
     this.wait();
   }
   nums++;
   System.out.println(Thread.currentThread().getName() + "->=" + nums);
   //通知其它线程,我+1完成了
   this.notifyAll();
}
//消费者代码
public synchronized void decrement() throws InterruptedException {
        //消费等待条件
        if (nums == 0) {
            //等待
            this.wait();
        }
        nums--;
        System.out.println(Thread.currentThread().getName() + "->=" + nums);
        //通知其它线程,我-1完成了
        this.notifyAll();
    }

在这里插入图片描述

所以要使用while来进行条件判断

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java多线程中条件判断为啥要用while判断 的相关文章

  • JDK 文档是语言规范的一部分吗?

    只有一名官员Java语言规范 https docs oracle com javase specs jls se8 html index html所有 Java 实现都必须遵守它 API文档怎么样 所有Java实现都需要遵守吗这个版本 ht
  • 是否有任何简单(且最新)的 Java 框架可用于在 Swing 应用程序中嵌入电影?

    我正在构建一个小型 Swing 应用程序 我想在其中嵌入一部电影 重要的是 这个应用程序是一个 WebStart 应用程序 并且该库应该能够打包在我启动的 jnlp 中 即 不依赖于本机库 我知道并尝试过 JMF 但我认为与其他框架相比 其
  • 不同类型的数组

    是否可以有一个包含两种不同类型数据的数组 我想要一个包含双精度型和字符串的数组 我尝试过 ArrayList
  • 当客户端关闭连接时,Spring StreamingResponseBody 请求线程未清理

    我在控制器中有一个端点 它返回一个StreamingResponseBody 用于向客户端发送文件 其代码大致如下 RestController RequestMapping value api public class Controlle
  • 使用 JUnit 时,有没有办法验证测试方法中是否调用了 try/catch 指令的 Catch 部分?

    例如 如果我想测试以下课程 public class SomeClass public void someMethod try Some code where comething could go wrong catch Exception
  • ConcurrentHashMap 内部是如何工作的?

    我正在阅读有关 Java 并发性的 Oracle 官方文档 我想知道Collection由返回 public static
  • 需要使用 joda 进行灵活的日期时间转换

    我想使用 joda 解析电子邮件中的日期时间字符串 不幸的是我得到了各种不同的格式 例如 Wed 19 Jan 2011 12 52 31 0600 Wed 19 Jan 2011 10 15 34 0800 PST Wed 19 Jan
  • 是否可以通过编程方式查找 logback 日志文件?

    自动附加日志文件以支持电子邮件会很有用 我可以以编程方式设置路径 如以编程方式设置 Logback Appender 路径 https stackoverflow com questions 3803184 setting logback
  • 如何检测 Java 字符串中的 unicode 字符?

    假设我有一个包含 的字符串 我如何找到所有这些 un icode 字符 我应该测试他们的代码吗 我该怎么做呢 例如 给定字符串 A X 我想将其转换为 AYXY 我想对其他 unicode 字符做同样的事情 并且我不想将它们存储在某种翻译映
  • 使用 Guice 优化注册表

    你好 今天思考了一种优化 有一些疑问 语境 我正在使用 Guice 2 进行 Java 开发 在我的网络应用程序中 我有一个转换器注册表 可以即时转换为某种类型 转换器描述如下 public class StringToBoolean im
  • 生成的序列以 1 开头,而不是注释中设置的 1000

    我想请求一些有关 Hibernate 创建的数据库序列的帮助 我有这个注释 下面的代码 在我的实体类中 以便为合作伙伴表提供单独的序列 我希望序列以 1000 开头 因为我在部署期间使用 import sql 将测试数据插入数据库 并且我希
  • Java Swing For mac 中的 DJ Native Swing 浏览器

    我有一个用 Swing 制作的 Java 应用程序 并且使用了一个 DJ Native Swing 浏览器 当我尝试在 OS X 上使用它时 它抛出了一个NoClassDefFoundError尽管我添加了 swt jar 但始终如此 有人
  • 是否可以使用 Java Guava 将函数应用于集合?

    我想使用 Guava 将函数应用于集合 地图等 基本上 我需要调整 a 的行和列的大小Table分别使所有行和列的大小相同 执行如下操作 Table
  • “无法实例化活动”错误

    我的一个 Android 应用程序拥有大约 100 000 个用户 每周大约 10 次 我会通过 Google 的市场工具向我报告以下异常情况 java lang RuntimeException Unable to instantiate
  • Android:无法发送http post

    我一直在绞尽脑汁试图弄清楚如何在 Android 中发送 post 方法 这就是我的代码的样子 public class HomeActivity extends Activity implements OnClickListener pr
  • OpenCSV:将嵌套 Bean 映射到 CSV 文件

    我正在尝试将 bean 映射到 CSV 文件 但问题是我的 bean 具有其他嵌套 bean 作为属性 所发生的情况是 OpenCSV 遍历属性找到一个 bean 然后进入其中并映射该 bean 内的所有数据 如果找到另一个 bean 它就
  • 如何重新启动死线程? [复制]

    这个问题在这里已经有答案了 有哪些不同的可能性可以带来死线程回到可运行状态 如果您查看线程生命周期图像 就会发现一旦线程终止 您就无法返回到新位置 So 没有办法将死线程恢复到可运行状态 相反 您应该创建一个新的 Thread 实例
  • Java中HashMap和ArrayList的区别?

    在爪哇 ArrayList and HashMap被用作集合 但我不明白我们应该在哪些情况下使用ArrayList以及使用时间HashMap 他们两者之间的主要区别是什么 您具体询问的是 ArrayList 和 HashMap 但我认为要完
  • 如何使用play框架上传多个文件?

    我在用play framework 2 1 2 使用java我正在创建视图来上传多个文件 我的代码在这里 form action routes upload up enctype gt multipart form data
  • 洪水填充优化:尝试使用队列

    我正在尝试创建一种填充方法 该方法采用用户指定的初始坐标 检查字符 然后根据需要更改它 这样做之后 它会检查相邻的方块并重复该过程 经过一番研究 我遇到了洪水填充算法并尝试了该算法 它可以工作 但无法满足我对 250 x 250 个字符的数

随机推荐

  • 【一千个论文合集】计算机科学的26个细分领域近年必读论文集合

    文章目录 1 机器学习 2 计算机视觉 3 自然语言处理 4 数据挖掘 5 机器人 6 知识工程 7 模式识别 8 信息检索与推荐 9 数据库 10 人机交互 11 计算机图形学 12 多媒体 13 可视化 14 数据科学 15 安全与隐私
  • vue利用 sortable 完成表格拖拽

    先讲一下vue2 使用sortable完成表格拖拽 不只是表格 div也可以实现 但我项目中是表格拖拽 github地址 安装 npm install sortablejs save 使用 我的项目中是拖拽一个小按钮移动 而不是整行
  • umi:配置式路由

    场景描述 很多时候 我们需要做到简单的路由拦截 比如用户未登录的时候 我们需要跳转到登录页面 等到用户登录后在重新跳转到之前的页面 而很多情况下这些是约定式路由无法完成的 就需要我们配置式路由 论述 umi自带的约定式路由 可以自动的生成路
  • element-ui的table表格实现跨页多选及回显效果

    效果图 安装 Element ui 和 egrid 基于 Element UI Table 组件封装的高阶表格组件 可无缝支持 element 的 table 组件 npm i element ui S npm i egrid S 引入 E
  • kubectl常用命令

    alias k kubectl alias kc k create f alias kgp k get pods alias kdp k describe pods alias kdep k delete pods alias kl k l
  • mysql 判断字符串相等_「8」掌握MySQL比较运算符是很有必要的

    本文要的主题就是MySQL比较运算符 也就是通过各类案例来看看其运行得到的结果是什么 以及掌握其规则 首先 我们看看比较运算符有哪些种类 接下来我们就通过案例的案例的方式来逐一学习 1 等于运算符 是用来判断数字 字符串和表达式是否相等 如
  • 面向对象编程中composition、aggregation、association的区别

    在面向对象程序设计中 对象的关系主要有三种 composition aggregation association composition 组合 复合 对象x的生命期由唯一拥有者owner控制 owner析构时会把x同步析构 例如Engin
  • uni-app css尺寸单位rpx介绍

    一 前言 1 在使用uni app开发小程序时支持的尺寸单位如下 1 基础单位 px rpx 2 h5单位 rem vm vh 2 rpx是微信小程序提出的一种响应式px 二 rpx介绍 1 现实情况下 ui设计师只提供一个分辨率的图 严格
  • css层叠样式表——css基础介绍

    css层叠样式表第一天 css层叠样式表01 css层叠样式表第一天 css介绍 css语法 html标签全局属性 引入css样式的方式 知识点应用 css介绍 css是Cascading Style Sheet的缩写 中文 层叠样式表 是
  • M1 Pro 安卓模拟器+Xposed环境

    吐槽 最近换了台mac 发现mac对程序员真的太友好了 一些环境配置起来很方便 借助brew几乎都是一行命令的事 但是有一些环境还不是那么好配 在这做一下记录 这次要说的是安卓模拟器 我本人是有一台Google Pixel真机的 插上数据线
  • Python-Tensorflow猫狗数据集分类,96%的准确率

    import tensorflow as tf from tensorflow import keras from tensorflow keras import layers curl O https download microsoft
  • 多环境配置

    Mybatis plus 需要添加一个依赖 这个是baomidou官方的动态数据源包
  • 机器学习 | 图像检索开源项目合集

    1 Trace moe 图像反向搜索动漫场景 使用动漫截图搜索该场景的拍摄地 它告诉你该动画在日本动漫中出现的是哪个动画 哪个情节以及确切的时间 https github com soruly trace moe 2 Awesome Cbi
  • 【数字图像处理系列五】图像滤波之空间滤波:图像平滑降噪和图像锐化

    本系列python版本 python3 5 4 本系列opencv python版本 opencv python3 4 2 17 本系列使用的开发环境是jupyter notebook 是一个python的交互式开发环境 测试十分方便 并集
  • Flutter 学习笔记 《二》 编辑器设置

    1 编辑器设置 open a Simulator 2 运行 Flutter 项目 运行 flutter run启动您的应 一 iOS 设置 安装 Xcode 安装到iOS设备 要将您的Flutter应用安装到iOS真机设备 您需要一些额外的
  • pip install安装路径介绍

    本文转载自 https www python100 com html 7749O60EJDFE html 更新 2023 05 26 10 55 pip是Python语言中的一个包管理工具 通过pip我们可以安装 升级 卸载Python包
  • linux 文件转utf 8,在Linux系统下把文件转换为UTF-8编码

    转换环境Linux系统 整个项目要转换为多语言版本 所有文件储存格式由原来GB2312转换为UTF 8编码 为了方便 借助iconv命令写了下面脚本 bin bash if z 1 then echo Please input a dire
  • Json_c++ json api 的个人总结

    http hi baidu com it ibear item 936f9644f0569f9f833ae12d json object的格式 注意 一个json对象内可以包含多个json对象 latitude 116 4009189605
  • STATA长面板数据分析

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 一 面板数据基本概念 二 STATA长面板数据分析步骤 1 数据导入与处理 2 描述性统计 3 单位根检验 4 协整检验 5 模型的筛选 6 模型的检验 7 模型的
  • Java多线程中条件判断为啥要用while判断

    Java多线程中条件判断 一 使用if判断造成的线程虚假唤醒问题 我们在使用线程时 进行条件判断时 往往会先考虑使用if进行判断 在线程进行等待时就会出现不确定的结果 先来看看两个线程下的操作 多线程编程模式 1 高聚低合前提下 线程操作资