java多线程中wait方法要在while中调用而非if中

二维电磁仿真中能量源边界设置的物理本质与工程实践 电磁仿真中的‘能量源’并非简单输入场值,而是满足麦克斯韦方程组约束、实现功率守恒与波前自洽的物理建模过程。其核心原理在于电场与磁场的耦合驱动、Poynting矢量的数值积分一致性,以及二维降维带来的模式截断与色散修正。技术价值体现在提升S参数精度、抑制非物理振荡、支撑光子晶体与超构表面等前沿设计。典型应用场景涵盖平面波入射、波导激励、周期性结构斜入射及时域脉冲仿真。本文聚焦二维电磁仿真中‘能量源’与‘边界条件’两大热词,系统拆解从物理建模到软件配置的全链路逻辑。 阅读详情

开门见山直说:

       在java多线程情况下,当线程被wait后,又通过notify方法唤醒时,在if情况下被唤醒,程序从哪里wait的就从哪里继续执行,在while的情况下被唤醒,程序依旧会从哪里wait的继续往下执行,但是,在执行之前会先对循环条件进行判断,满足条件继续wait,不满足条件继续执行。而if语句不会再对条件进行判断,直接继续执行。所以在多线程情况下,可能会有多个线程再对资源进行修改,当被wait的线程被唤醒时,有其他线程已经将资源进行修改过了,导致 while的条件发生变化(不再满足)。而刚唤醒的线程根本不知道,所以导致异常。

实例:

class SynStack
{
    private char[] data = new char[6];
    private int cnt = 0; //表示数组有效元素的个数

    public synchronized void push(char ch)
    {
        if (cnt >= data.length)
        {
            try
            {
                System.out.println("生产线程"+Thread.currentThread().getName()+"准备休眠");
                this.wait();
                System.out.println("生产线程"+Thread.currentThread().getName()+"休眠结束了");
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        this.notify();
        data[cnt] = ch;
        ++cnt;
        System.out.printf("生产线程"+Thread.currentThread().getName()+"正在生产第%d个产品,该产品是: %c\n", cnt, ch);
    }

    public synchronized char pop()
    {
        char ch;
        if (cnt <= 0)
        {
            try
            {
                System.out.println("消费线程"+Thread.currentThread().getName()+"准备休眠");
                this.wait();
                System.out.println("消费线程"+Thread.currentThread().getName()+"休眠结束了");
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        this.notify();
        ch = data[cnt-1];
        System.out.printf("消费线程"+Thread.currentThread().getName()+"正在消费第%d个产品,该产品是: %c\n", cnt, ch);
        --cnt;
        return ch;
    }
}

class Producer implements Runnable
{
    private SynStack ss = null;
    public Producer(SynStack ss)
    {
        this.ss = ss;
    }

    public void run()
    {
        char ch;
        for (int i=0; i<10; ++i)
        {
            ch = (char)('a'+i);
            ss.push(ch);
        }
    }
}

class Consumer implements Runnable
{
    private SynStack ss = null;

    public Consumer(SynStack ss)
    {
        this.ss = ss;
    }

    public void run()
    {
        for (int i=0; i<10; ++i)
        {
            ss.pop();
        }
    }
}


public class TestPC2 {

    public static void main(String[] args)
    {
        SynStack ss = new SynStack();
        Producer p = new Producer(ss);
        Consumer c = new Consumer(ss);


        Thread t1 = new Thread(p);
        t1.setName("1号");
        t1.start();
        /*Thread t2 = new Thread(p);
        t2.setName("2号");
        t2.start();*/

        Thread t6 = new Thread(c);
        t6.setName("3号");
        t6.start();
        Thread t7 = new Thread(c);
        t7.setName("4号");
        t7.start();
    }

}

补充:

       在思考上面的问题的时候,发现了一个很好玩的东西,就是通过new ArrayList<String>()来声明一个新对象的时候,其实这个对象不是空的,里面是有一个值的也就是anyString,但是这个值是不计数的,我们通过size()获取的元素大小是直接获取的ArrayList的size成员变量;

/**
 * The size of the ArrayList (the number of elements it contains).
 *
 * @serial
 */
private int size;
Android Binder——数据传递载体(二十一) 同一进程间的对象传递都是通过引用来做的,因而本质上就是传递了一个内存地址。而跨进程采用了虚拟内存机制,两个进程都有自己独立的内存地址空间,所以跨进程传递的地址值是无效的。进程间的数据传递是 Binder 机制中的重要一环,Android 系统中担负这一重任的就是 Parcel。Parcel 是一种数据的载体,用于承载希望通过 IBinder 发送的相关信息(包括数据和对象引用)。正是基于 Parcel 这种跨进程传输数据的能力,进程间的 IPC 通信才能更加平滑可靠。 阅读详情

相关推荐

无符号整数、带符号整数溢出问题

让我们详细讲解一下带符号整数溢出和无符号整数溢出问题中,符号标志位 (SF)、零标志位 (ZF) 和进位标志位 (CF) 的行为方式

weixin_49342084的博客 2086

wait() 方法的判断逻辑需要用while判断,不能用if判断,以及notify的唤醒线程的不确定性

例如,我们有一个有界队列,有生产者向队列里插入元素,有消费者从队列中获取并删除元素。 如果队列满了,则要阻塞生产者,等队列不满了再添加元素; 如果队列里没有元素,则要阻塞消费者,等到有元素了再进行消费。 因此,当生产者向队列里放进一个元素后,或者当消费者消费了队列里的一个元素后,就可以notify被阻塞的线程。 我们通过一个简单的例子来看wait()方法的判断逻辑要用while判断,而不是用if判断 import java.util.ArrayList; import java.util.Lis

ystyaoshengting的专栏 1076

【探秘】二维异形件重叠移除算法:从度量到消除的实战解析

本文深入解析二维异形件重叠移除算法的核心技术与实战应用,涵盖重叠度量、零件扰动策略及消除方法。通过NFP(临界多边形)技术、空间分区加速等优化手段,有效解决异形件排版中的重叠问题,提升材料利用率和计算效率。适合制造业、CAD软件开发者及算法工程师参考。

weixin_28698059的博客 251

你是如何使用 wait () 方法的?使用 if 还是 while

虚假唤醒是指线程在没有被显式唤醒(例如通过。

2401_87705025的博客 578

SPECweb2009调优指南

 SPECweb2009 是衡量 Web 服务器性能和能效的标准化基准,可以对 Web 服务器的并发数进行性能测试,评测 Web 服务器能够支持的最大同时连接数的客户端/服务器(每秒能够响应的最大请求数)。为充分利用服务器性能,提升SPECweb2009测试结果,可通过增大系统进程数、优化服务器软件参数、绑核以及优化参数等。

developersupport的博客 2607

PotPlayer播放4K HDR电影时,如何正确设置LAV解码器与MadVR渲染器避免色彩失真?

本文详细介绍了如何在PotPlayer中正确配置LAV解码器与MadVR渲染器,以解决播放4K HDR电影时的色彩失真问题。从组件安装、参数设置到显卡协同配置,提供了一套完整的端到端解决方案,帮助影音爱好者获得最佳的视觉体验。

weixin_28732953的博客 440

线程间通信 wait/notify

一、简介 每个线程在运行的时候,仅仅只是孤立运行的话,带来的价值是非常小的,如果多个线程能够相互配合去完成工作,那么在多线程场景中会带来非常大的价值。 如一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作。前者是生产者,后者是消费者。在 Java 语言中使用如下代码可以实现该功能。 while (value != desire) { Thread.sleep(1000); ...

hncboy的博客 368

Python爬虫博客:爬取碳排放交易数据——使用最新技术的完整实现

通过上述方法,我们可以构建一个高效的爬虫,爬取碳排放交易市场的数据并进行分析。这个项目不仅展示了如何处理静态和动态网页,还提供了如何存储数据、分析数据和可视化结果的技巧。随着爬虫技术的不断进步,我们可以进一步提升爬取效率和数据分析能力。如果你希望更深入了解如何进行数据挖掘和机器学习分析,可以尝试将碳排放数据与其他经济数据结合,利用机器学习模型进行趋势预测或决策支持。

2201_76125261的博客 351

面试官:你是如何调用 wait()方法的?使用 if 块还是循环?为什么?

wait() 方法应该在循环调用 问:为什么是 while 而不是 if ? 大多数人都知道常见的使用 synchronized 代码: synchronized(obj){ while(checkpass){ wait(); } //doyourbusiness } 那么问题是为啥这里是 while 而不是 if 呢?这个问题我最开始也想了很久,按理来说已经在 synchronized 块里面了嘛,就不需要了。这个也是我前面一直是这么认...

qfguan的博客 1239

HITECH海泰克触摸屏如何使用串口进行程序的下载和上传(拨码设置)以及离散量报警相关设定?

HITECH海泰克触摸屏如何使用串口进行程序的下载和上传(拨码设置)以及离散量报警相关设定? 首先,我们进行触摸屏一侧的设置,如下图所示: 触摸屏背后有拨码开关,当我们需要上传或下载程序时,需要将7#开关拨到上面; 左侧是DC24V电源接口; 下方是COM1、COM2和COM3通信端口,选择我们需要的端口后,插上通信电缆,拔掉24V电源,然后重新上电; 然后,屏幕会进入如下图所示界面,此时显示当前选择的端口为COM2,我们点击F2“config”,进入设置界面, 可以看到COM2端口是“Enabled”

Robot_PLC_HMI_Automation 3万+

手把手教你完成基于YOLOv8的水果/商品/食堂/蔬菜/饮料/书籍识别与计价系统,前台+后台管理系统

手把手教你完成基于YOLOv8的商店的水果/商品/食堂/蔬菜/饮料/书籍识别与计价系统,前台+后台管理员系统,可进行目标检测的操作和展示,实现对图片、视频和摄像头的实时目标检测

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 2456

关于使用if和while包裹wait方法

结论:在需要先判断条件,再使用wait方法的情况下,使用while。原因是:线程使用wait放弃锁后,线程会停在wait方法的位置,等到线程被notify唤醒,并重新获得锁,线程会继续执行后面的操作。如果使用if语句块,线程重新获取锁并执行完if块中的语句后,不会再判断一次if条件,而是直接执行if外的语句,从而引起错误的执行流程。 错误示例代码: /** * Author: Aipande * Description:生产者消费者模型 * Date-Of-Create:2020/10/22-8:45

aipande143的博客 1157

【路径规划】Theta_star算法机器人栅格地图最短路径规划【含Matlab源码 2618期】

Theta_star算法机器人栅格地图最短路径规划 完整的代码,方可运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 363

生产者消费者模式中条件判断是使用while而不是if

永远在循环(loop)里调用 wait 和 notify,不是在 If 语句现在你知道wait应该永远在被synchronized的背景下和那个被多线程共享的对象上调用,下一个一定要记住的问题就是,你应该永远在while循环,而不是if语句中调用wait。因为线程是在某些条件下等待的——在我们的例子里,即“如果缓冲区队列是满的话,那么生产者线程应该等待”,你可能直觉就会写一个if语句。但if语句存...

Mike_CSU的博客 1452

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

线程状态模型与synchronized的wait与notify方法

1. 线程状态图 这是线程的7状态模型图,常见的7大状态之间的转换关系也在上面。多线程之间的通信主要用到4个方法,wait()、wait(long time)、notify()、notifyAll(),其他方法在多线程基础中都有介绍。 wait():作用是使当前线程从调用处中断并且释放锁转入等待队列,直到收到notify或者notifyAll的通知才能从等待队列转入锁池队列,没有收到停止会一直死等。 wait(long time):相比wait多了一个等待的时间time,如果经过ti..

好好学java 1042

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

java notify 用法_Java 中 wait, notify 和 notifyAll的正确使用 – 以生产者消费者模型为例...

如何使用Wait尽管关于wait和notify的概念很基础,它们也都是Object类的函数,但用它们来写代码却并不简单。如果你在面试中让应聘者来手写代码,用wait和notify解决生产者消费者问题,我几乎可以肯定他们中的大多数都会无所适从或者犯下一些错误,例如在错误的地方使用 synchronized 关键词,没有对正确的对象使用wait,或者没有遵循规范的代码方法。说实话,这个问题对于不常使用...

weixin_39783156的博客 225

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

notify和notifyAll的区别

转自:http://www.importnew.com/16453.html 如果某些线程在等待某些条件触发,那当那些条件为真时,你可以用 notify 和 notifyAll 来通知那些等待中的线程重新开始运行。不同之处在于,notify 仅仅通知一个线程,并且我们不知道哪个线程会收到通知,然而 notifyAll 会通知所有等待中的线程。换言之,如果只有一个线程在等待一个信号灯,notify...

一只苟延残喘的卑微蝼蚁 1659

多线程-生产者消费者(synchronized同步)

正解博客:https://blog.youkuaiyun.com/u011863767/article/details/59731447 永远在循环(loop)里调用 wait 和 notify,不是在 If 语句 现在你知道wait应该永远在被synchronized的背景下和那个被多线程共享的对象上调用,下一个一定要记住的问题就是,你应该永远在while循环,而不是if语句中调用wait。因为线程是在...

weixin_33910460的博客 172

java 调用其他线程_java-当另一个线程通知线程执行时,线程在哪...

被通知的线程需要重新获取锁,但是重新获取发生在等待调用中,并且线程从wait方法返回后就具有了锁,然后在第3行开始执行.Peter’s answer是正确的(1) .The thread T is then removed from the wait set for this object and re-enabled for thread scheduling. It then competes...

weixin_36072221的博客 477

java多线程情况下,while和if的区别

在多线程情况下,如果一个线程进入了if语句块中,在if语句块中执行了wait方法,该线程处于等待(wait)状态,如果该线程被唤醒(notify),不管if的条件是否发生了变化,该线程会执行wait之后的代码,并且会跳出if语句块执行if语句块外面的代码   如果是while,被唤醒了之后,会继续执行wait方法之后的代码,代码块里面的代码执行完了会继续判断条件,如果为true,会继续执行wh...

u013958151的博客 3153

java多线程wait时为什么要用while而不是if

对于java多线程的wait()方法,我们在jdk1.6的说明文档里可以看到这样一段话   从上面的截图,我们可以看出,在使用wait方法时,需要使用while循环来判断条件十分满足,而不是if,那么我们思考以下,如果使用if会怎么样? 为方便讲解,我们来看一个被广泛使用的生产消费的例子。代码部分参考  郝斌java视频教程  部分改编。 /* 生产和消费 */ packag...

worldchinalee的博客 1万+

java多线程wait判断要用while替换if

java多线程wait判断要用while替换if 代码参考 【狂神说Java】JUC并发编程最新版通俗易懂. 执行测试类 两个方法,每个方法两条线程 public class A { public static void main(String[] args) { Data data = new Data(); new Thread(()->{ for (int i = 0;i<5;i++){ tr

qq_38008470的博客 584

Java 并发编程核心:wait() 方法为何必须搭配 while 而非 if

用 wait() 时,条件判断必须用 while,永不用 if。原因:防御伪唤醒(语言规范允许的行为)。掌握 wait()/notify() 是理解 Java 并发的基础。生产环境优先使用 java.util.concurrent 高层工具,更安全、更高效。

qq_62861638的博客 976

java多线程wait为什么用while判断

最近在学习线程,发现一个有意思的面试题,wait为什么用while而不能用if? 这个是一个固定容量同步容器,拥有put和get方法 package yxxy.c_021; import java.util.LinkedList; import java.util.concurrent.TimeUnit; public class MyContainer1<T> { final ...

qq_39552993的博客 719

java多线程wait,notify使用时,不能用if的原因,以及为什么要用while

简介: 今天看面试题时,看到wait的使用里面有一句话是wait,notify要用while,而不能用if。想了半天不知道为什么,看到大佬说在生产者消费者模式下会出错。于是我测试了如下 用if举例 写一个工厂类,有生产和消费方法,以及生产的产品数组 public class Factory { //存放生产的数组 public char[] data = new char[5]; ...

qq_42034205的博客 1351
上一篇: 关于Set集合不安全问题的源码和解决分析
下一篇: Condition的分组机制
咕咚走了
博客等级 码龄9年 1粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值