notifyall如何在 Java 中正确使用 wait,notify 和 notifyAll

notifyall  时间:2021-06-10  阅读:()

在Java根类java.lang.Object中包含了3个重载的wait()方法以及 notify()方法和notifyAll()

wait() 导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。

wait(long timeout) 导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。

wait(long timeout, int nanos) 导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。

notify() 唤醒在此对象监视器上等待的单个线程。

notifyAll() 唤醒在此对象监视器上等待的所有线程。

object类的六个方法都有什么?分别是什么意思?有什么用途?

protected Object clone() 创建并返回此对象的一个副本。

boolean equals(Object obj) 指示其他某个对象是否与此对象“相等”。

protected void finalize() 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

Class getClass() 返回此 Object 的运行时类。

int hashCode() 返回该对象的哈希码值。

void notify() 唤醒在此对象监视器上等待的单个线程。

void notifyAll() 唤醒在此对象监视器上等待的所有线程。

String toString() 返回该对象的字符串表示。

void wait() 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。

void wait(long timeout) 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。

void wait(long timeout, int nanos) 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导

IllegalArgumentException是什么错误

代码太乱了没怎么看 做级联操作的话,不需要一次性将5个下拉框都填充值,只需要填充第一级下拉框,然后触发第一级下拉框的onChange事件时通过dwr获取第二级下拉框的数据,以此类推. 以上的报错信息是方法的传参有问题,你可能传了一个null到后台,你可以debug一下后台的获取数据的方法,看看是哪个参数有问题.

在什么地方wait()方法、notify()及notifyAll()方法可以被使用?

比如:生产者和消费者共同来操作堆栈吧,消费者从堆中取产品,生产者放产品! 只有当生产者把产品放到了堆中,消费者才可以取到产品,不然就会出错! 当你用两个线程来分别控制生产者和消费者时.他们是同时的. 你可以用wait()方法让消费者那个线程停下来等生产者把产品放到堆里,放完之后,消费者才可以取. 当生产者放完了产品之后,就用notify()通知wait(),让消费者获得运行的权利! 希望悄能听清楚了!?呵呵!

如何在 Java 中正确使用 wait,notify 和 notifyAll

wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视。

本文对这些关键字的使用进行了描述。

在 Java 中可以用 wait、notify 和 notifyAll 来实现线程间的通信。



举个例子,如果你的Java程序中有两个线程——即生产者和消费者,那么生产者可以通知消费者,让消费者开始消耗数据,因为队列缓 冲区中有内容待消费(不为空)。

相应的,消费者可以通知生产者可以开始生成更多的数据,因为当它消耗掉某些数据后缓冲区不再为满。

我们可以利用wait()来让一个线程在某些条件下暂停运行。

例如,在生产者消费者模型中,生产者线程在缓冲区为满的时候,消费者在缓冲区为空的时 候,都应该暂停运行。

如果某些线程在等待某些条件触发,那当那些条件为真时,你可以用 notify 和 notifyAll 来通知那些等待中的线程重新开始运行。

不同之处在于,notify 仅仅通知一个线程,并且我们不知道哪个线程会收到通知,然而 notifyAll 会通知所有等待中的线程。

换言之,如果只有一个线程在等待一个信号灯,notify和notifyAll都会通知到这个线程。

但如果多个线程在等待这个信 号灯,那么notify只会通知到其中一个,而其它线程并不会收到任何通知,而notifyAll会唤醒所有等待中的线程。

在这篇文章中你将会学到如何使用 wait、notify 和 notifyAll 来实现线程间的通信,从而解决生产者消费者问题。

如果你想要更深入地学习Java中的多线程同步问题,我强烈推荐阅读Brian Goetz所著的《Java Concurrency in Practice | Java 并发实践》,不读这本书你的 Java 多线程征程就不完整哦!这是我最向Java开发者推荐的书之一。

如何使用Wait 尽管关于wait和notify的概念很基础,它们也都是Object类的函数,但用它们来写代码却并不简单。

如果你在面试中让应聘者来手写代码, 用wait和notify解决生产者消费者问题,我几乎可以肯定他们中的大多数都会无所适从或者犯下一些错误,例如在错误的地方使用 synchronized 关键词,没有对正确的对象使用wait,或者没有遵循规范的代码方法。

说实话,这个问题对于不常使用它们的程序员来说确实令人感觉比较头疼。

第一个问题就是,我们怎么在代码里使用wait()呢?因为wait()并不是Thread类下的函数,我们并不能使用 Thread.call()。

事实上很多Java程序员都喜欢这么写,因为它们习惯了使用Thread.sleep(),所以他们会试图使用wait() 来达成相同的目的,但很快他们就会发现这并不能顺利解决问题。

正确的方法是对在多线程间共享的那个Object来使用wait。

在生产者消费者问题中,这 个共享的Object就是那个缓冲区队列。

第二个问题是,既然我们应该在synchronized的函数或是对象里调用wait,那哪个对象应该被synchronized呢?答案是,那个 你希望上锁的对象就应该被synchronized,即那个在多个线程间被共享的对象。

在生产者消费者问题中,应该被synchronized的就是那个 缓冲区队列。

(我觉得这里是英文原文有问题……本来那个句末就不应该是问号不然不太通……) 永远在循环(loop)里调用 wait 和 notify,不是在 If 语句 现在你知道wait应该永远在被synchronized的背景下和那个被多线程共享的对象上调用,下一个一定要记住的问题就是,你应该永远在 while循环,而不是if语句中调用wait。

因为线程是在某些条件下等待的——在我们的例子里,即“如果缓冲区队列是满的话,那么生产者线程应该等 待”,你可能直觉就会写一个if语句。

但if语句存在一些微妙的小问题,导致即使条件没被满足,你的线程你也有可能被错误地唤醒。

所以如果你不在线程被唤 醒后再次使用while循环检查唤醒条件是否被满足,你的程序就有可能会出错——例如在缓冲区为满的时候生产者继续生成数据,或者缓冲区为空的时候消费者 开始小号数据。

所以记住,永远在while循环而不是if语句中使用wait!我会推荐阅读《Effective Java》,这是关于如何正确使用wait和notify的最好的参考资料。

基于以上认知,下面这个是使用wait和notify函数的规范代码模板: // The standard idiom for calling the wait method in Java synchronized (sharedObject) { while (condition) { sharedObject.wait(); // (Releases lock, and reacquires on wakeup) } // do action based upon condition e.g. take or put into queue } 就像我之前说的一样,在while循环里使用wait的目的,是在线程被唤醒的前后都持续检查条件是否被满足。

如果条件并未改变,wait被调用之前notify的唤醒通知就来了,那么这个线程并不能保证被唤醒,有可能会导致死锁问题。

Java wait(), notify(), notifyAll() 范例 下面我们提供一个使用wait和notify的范例程序。

在这个程序里,我们使用了上文所述的一些代码规范。

我们有两个线程,分别名为 PRODUCER(生产者)和CONSUMER(消费者),他们分别继承了了Producer和Consumer类,而Producer和 Consumer都继承了Thread类。

Producer和Consumer想要实现的代码逻辑都在run()函数内。

Main线程开始了生产者和消费 者线程,并声明了一个LinkedList作为缓冲区队列(在Java中,LinkedList实现了队列的接口)。

生产者在无限循环中持续往 LinkedList里插入随机整数直到LinkedList满。

我们在while(queue.size == maxSize)循环语句中检查这个条件。

请注意到我们在做这个检查条件之前已经在队列对象上使用了synchronized关键词,因而其它线程不能在 我们检查条件时改变这个队列。

如果队列满了,那么PRODUCER线程会在CONSUMER线程消耗掉队列里的任意一个整数,并用notify来通知 PRODUCER线程之前持续等待。

在我们的例子中,wait和notify都是使用在同一个共享对象上的。

萤光云(13.25元)香港CN2 新购首月6.5折

萤光云怎么样?萤光云是一家国人云厂商,总部位于福建福州。其成立于2002年,主打高防云服务器产品,主要提供福州、北京、上海BGP和香港CN2节点。萤光云的高防云服务器自带50G防御,适合高防建站、游戏高防等业务。目前萤光云推出北京云服务器优惠活动,机房为北京BGP机房,购买北京云服务器可享受6.5折优惠+51元代金券(折扣和代金券可叠加使用)。活动期间还支持申请免费试用,需提交工单开通免费试用体验...

€4.99/月Contabo云服务器,美国高性价比VPS/4核8G内存200G SSD存储

Contabo是一家运营了20多年的欧洲老牌主机商,之前主要是运营德国数据中心,Contabo在今年4月份增设新加坡数据中心,近期同时新增了美国纽约和西雅图数据中心。全球布局基本完成,目前可选的数据中心包括:德国本土、美国东部(纽约)、美国西部(西雅图)、美国中部(圣路易斯)和亚洲的新加坡数据中心。Contabo的之前国外主机测评网站有多次介绍,他们家的特点就是性价比高,而且这个高不是一般的高,是...

香港 E5-2650 16G 10M 900元首月 美国 E5-2660 V2 16G 100M 688元/月 华纳云

华纳云双11钜惠出海:CN2海外物理服务器终身价688元/月,香港/美国机房,免费送20G DDos防御,50M CN2或100M国际带宽可选,(文内附带测评)华纳云作为一家专业的全球数据中心基础服务提供商,总部在香港,拥有香港政府颁发的商业登记证明,APNIC 和 ARIN 会员单位。主营香港服务器、美国服务器、香港/美国OpenStack云服务器、香港高防物理服务器、美国高防服务器、香港高防I...

notifyall为你推荐
短信接口不用其他公司的短信接口,自己可以写短信接口吗。csonline2csol2房间人数是多少?能超过32人吗?求大神解答,尽可能详细,我需要CSOL2的情报谢谢。我水晶易表如何在win7环境和office2010环境下成功安装水晶易表企业资源管理系统企业管理系统都有什么功能orphanremovalhibernate一对多,操作一的一方,如何删除多的一方的数据。vga接口定义主板上的VGA接口有什么用?搜索引擎的概念什么叫搜索引擎?搜索引擎的类型有哪些?自定义表情QQ自定义表情数据挖掘项目将来想从事统计分析和数据挖掘,需要哪些技能asp大马问:ASP是什么?ASP根据什么制作木马的?ASP木马和大马有什么区别?
猫咪永久域名收藏地址 看国外视频直播vps 三级域名网站 万网域名解析 rak机房 英语简历模板word 名片模板psd 国外网站代理服务器 dd444 699美元 免费全能主机 傲盾官网 爱奇艺vip免费领取 域名与空间 备案空间 国内域名 wordpress中文主题 杭州电信宽带 香港博客 新网dns 更多