多线程中为什么wait()必须放在while循环中?

问题描述

网上挺多解释的,但是总感觉说的很含糊不够透彻,希望有真正理解的给菜鸟解释一下

解决方案

解决方案二:
wait()只有要求必须放在同步代码块或同步函数里吧
解决方案三:
没有必须放到while循环里这一说吧。不过通常都放到while循环里,因为很多线程同步块里都具有while循环。而你如果在while外面进行等待,基本上不能对程序进行控制。通常,你都需要分析或者控制循环里数据的执行情况。如果你的wait放在循环里,你就可以看到让循环停下来,让你看个清楚。如果放到外面,循环都执行完了。你到外面等上(wait)一百年,你也看不到你想看的情况。
解决方案四:
不放到循环里也不会报错的,就是这样的话wait就完全没作用了。
解决方案五:
网上说得比较多的可能是“虚假唤醒”,字面上不太好理解,这是多线程的一个特性,无论是windows还是linux,它们的多线程体系,都有这个特性。实际上,自己可以这样理解:比如调用notifyAll,唤醒对应锁上的所有线程,那所有wait的线程,就从wait方法返回了,但自己程序里的逻辑,是不是期望这种结果呢?所以针对每个wait,还要重复判断一下,确定此时是不是真的该醒来了,所以用for/while,而不是if判断。
解决方案六:
......好吧放入while循环这种事情并非强制性的不过wait()函数重点不光是阻塞而是释放当前资源交给其他线程处理LZ想想看如果其他线程处理完毕后唤醒阻塞中的线程的时候是不是要根据其他线程的处理结果重新制定执行流程呢?所以才用while使部分代码重新执行一次这不是必须的
解决方案七:
永远不要在循环的外面调用wait():在一个合格的多线程程序中,这是必须的。原因请查看《EffectiveJava》
解决方案八:
没听说必须放while里,放哪都是根据要实现的逻辑决定的
解决方案九:

解决方案十:
1、一般来说,wait肯定是在某个条件调用的,不是if就是while2、放在while里面,是防止出于waiting的对象被别的原因调用了唤醒方法,但是while里面的条件并没有满足(也可能当时满足了,但是由于别的线程操作后,又不满足了),就需要再次调用wait将其挂起。3、其实还有一点,就是while最好也被同步,这样不会导致错失信号。希望下面的文章对您有帮助:
解决方案十一:
一般放在while中,不是必须。。。
解决方案十二:
条件检查时候,应该放在while中,如果不是条件检查,可以不用。
解决方案十三:
先搞清楚为什么要用,才知道它用在什么地方。wait就是等待嘛,那为什么要等呢,那是比如你监视的端口或其它任务还没来,所以要等。就像一个狙击手,事先埋伏好,等有人来时就开枪,再来一个时再开枪。没人来时就要等,直到任务完成或其它中断任务的情部分发生。
解决方案十四:
如果是两个狙击手,在同时等待一个人,第一个人先打死了,第二个人还要再开一枪?针对两个线程同时等待还是要加这个while的
解决方案十五:
只要条件不满足,就一直wait,条件一旦满足了,就不wait了,while会一直判断,知道满足条件。synchronized(obj){while(<conditiondoesnothold>)obj.wait();...//Performactionappropriatetocondition}

如果是if,判断一次就完了,就木有while科学了。
解决方案:
简单一点的说,因为当一个等待线程醒来的时候,可能互斥量被其他的线程(notifyAll后可能又改变了互斥量的值,或者线程的假醒来,或者等等)又改变了,所以需要重复判断条件。
解决方案:
自己看代码,跟着运行轨迹大概走一遍,把思路理理,自然就懂了
解决方案:
if(等待的条件){wait();}dosomethingwhile()等待的条件{wait();}dosomething

if和while有什么区别呢。一个只执行一次,一个等到条件满足为直。根据实际需求而定。比如多线程读写同一个文件吧。要写入文件。当用if时,发现有其它线程在读,,执行一次就拜拜了。如果是while,我可等,等到都没有读写了,本线程在写入,其它时候都睡觉。

时间: 2024-12-02 21:48:10

多线程中为什么wait()必须放在while循环中?的相关文章

C# 如何让 多线程中每个线程间隔毫秒执行同一个方法?

问题描述 多线程的好处让效率提高很多倍,但是在某些情况下要求操作同一个方法的时候要求有间隔,这个间隔当然是毫秒级别的否则多线程的意义就体现不出来,本问题就是怎么让多线程中每个线程间隔毫秒执行同一个方法,测试代码如下:privatevoidbtnTest_Click(objectsender,EventArgse){TestManyThreadtest=newTestManyThread();test.Start();} 主要代码如下classTestManyThread{privatestati

(单例设计模式中)懒汉式与饿汉式在多线程中的不同

/*  目的:分析一下单例设计模式中,懒汉式与饿汉式在多线程中的不同!  开发时我们一般选择饿汉式,因为它简单明了,多线程中不会出现安全问题!  而饿汉式需要我们自己处理程序中存在的安全隐患,但是饿汉式的程序技术含量更高! */ /* class SinglePerson implements Runnable{    private static SinglePerson ss = new SinglePerson("hjz", 22);//恶汉式    private int ag

关于java多线程中的join方法

问题描述 关于java多线程中的join方法 1.主线程可能在子线程结束之前 结束吗?如果可能的话 举一个例子 2.如何理解join方法, 结合实际应用. 非常感谢非常感谢!!! 解决方案 关于join,参考:http://www.blogjava.net/jnbzwm/articles/330549.html 解决方案二: 主线程可能在子线程结束之前 结束吗 一般来说不可以,但是也不一定,如果子线程在执行finally中的代码,应该会等它执行完了才退出. 晕,join方法和什么"让主线程等子线

Java多线程中的两个问题

多线程|问题 多线程中Thread.stop()被废弃的原因:当调用Thread.stop()方法时,该线程将释放先前其控制的所有资源,而在线程没有正常执行完毕之前强迫Stop之后,这些资源可能处在一种不一致的状态,而这些处于不一致的状态的资源被其他的线程所使用之后,就可能会发生一些意想不到的错误.实现时间差事件的解决办法:在主线程中设置一个状态变量,在响应线程执行时,先sleep()一个固定的时间段,之后检查主线程的这个状态,如果这个状态不同就执行不同的操作,或停止执行.可以通过回调机制来实现

[C#学习]在多线程中如何调用Winform

问题的产生: 我的WinForm程序中有一个用于更新主窗口的工作线程(worker thread),但文档中却提示我不能在多线程中调用这个form(为什么?),而事实上我在调用时程序常常会崩掉.请问如何从多线程中调用form中的方法呢? 解答: 每一个从Control类中派生出来的WinForm类(包括Control类)都是依靠底层Windows消息和一个消息泵循环(message pump loop)来执行的.消息循环都必须有一个相对应的线程,因为发送到一个window的消息实际上只会被发送到

多线程中递归锁的实现.

在上一篇文章中,我已经阐述了多线程中简单锁的实现,可在结束的时候,我就提了那么一个问题,那就是如果在一个链表中进行插入时,要进行查询的操作,如果只是简单的锁,是没法实现的.所以"递归锁"就浮现于世了. 可能有些人看到递归这两个字,有点傻了眼,其实也没什么的,简单的介绍,就是进行简单的计数而已.刚开始引用锁的时候,就产生它,当在锁没有解开的时候,还要继续用锁,就简单的加一,解开一把就减一,当计数为零时,就把锁销毁掉.下面用程序来简单的阐述一下,递归锁是怎么实现的: 1.递归锁接口的定义.

在多线程中使用静态方法是否有线程安全问题

   类的成员分为两类,静态成员(static member)和实例成员(instance member).静态成员属于类,实例成员则属于对象,即类的实例.     简单讨论一下在一个类中使用静态字段(static field)和静态方法(static method)是否会有线程安全问题.      我们在知道, 静态字段(static field)和静态方法(static method)的调用是通过类来调用.静态方法不对特定的实例操作,只能访问静态成员.实例方法可对特定的实例操作,既能访问静态

文件操作-多线程中对文件进行写操作

问题描述 多线程中对文件进行写操作 我的多线程部分程序是这样的: UINT ClientThread(LPVOID pParam) { EnterCriticalSection(&cs); Cw_dispctrlDlg dlg=(Cw_dispctrlDlg)pParam; while(true) { -- -- dlg->file_net.Open(dlg->str_file_netpath, CFile::modeCreate | CFile::modeNoTruncate | C

代码-关于datagridview在多线程中滚动条无法使用的问题

问题描述 关于datagridview在多线程中滚动条无法使用的问题 private delegate void InvokeHandler(); //子线程中 this.Invoke(new InvokeHandler(delegate() { dataGridView1.DataSource = null; dataGridView1.DataSource = dgv_dt; })); 在网上查的到是这么解决的,但是我不知道该把代码贴在哪里,已经把datasource换成了自己的datata