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都是使用在同一个共享对象上的。

Vultr新用户省钱福利,最新可用优惠码/优惠券更新

如今我们无论线上还是线下选择商品的时候是不是习惯问问是不是有优惠活动,如果有的话会加速购买欲望。同样的,如果我们有准备选择Vultr商家云服务器的时候,也会问问是不是有Vultr优惠码或者优惠券这类。确实,目前Vultr商家有一些时候会有针对新注册用户赠送一定的优惠券活动。那就定期抽点时间在这篇文章中专门整理最新可用Vultr优惠码和商家促销活动。不过需要令我们老用户失望的,至少近五年我们看到Vu...

A400互联37.8元/季,香港节点cn2,cmi线路云服务器,1核/1G/10M/300G

A400互联怎么样?A400互联是一家成立于2020年的商家,A400互联是云服务器网(yuntue.com)首次发布的云主机商家。本次A400互联给大家带来的是,全新上线的香港节点,cmi+cn2线路,全场香港产品7折优惠,优惠码0711,A400互联,只为给你提供更快,更稳,更实惠的套餐,香港节点上线cn2+cmi线路云服务器,37.8元/季/1H/1G/10M/300G,云上日子,你我共享。...

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

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

notifyall为你推荐
换脸软件有什么p图软件可以换脸请求超时DNS请求超时,怎么办?mac地址克隆mac地址克隆是什么意思。svn服务器搭建怎样搭建本地svn服务器环境qq博客怎么开QQ博客啊!视频技术怎么做视频?js后退多级页面间的后退如何实现(js方法)审计平台什么是审计工具labelforhtml中label是什么意思啊?移动硬盘文件或目录损坏且无法读取双击移动硬盘提示文件或目录损坏且无法读取怎么回事?
最便宜虚拟主机 日本软银 台湾服务器 分销主机 mediafire 网站监控 国外php空间 ca4249 域名转向 宁波服务器 双11秒杀 流量计费 vip域名 paypal注册教程 512mb 监控服务器 域名转入 阿里云邮箱申请 双十二促销 万网服务器 更多