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

sharktech:老牌高防服务器商,跳楼价,1G独享$70、10G共享$240、10G独享$800

不知道大家是否注意到sharktech的所有服务器的带宽价格全部跳楼跳水,降幅简直不忍直视了,还没有见过这么便宜的独立服务器。根据不同的机房,价格也是不一样的。大带宽、不限流量比较适合建站、数据备份、做下载、做流媒体、做CDN等多种业务。 官方网站:https://www.sharktech.net 付款方式:比特币、信用卡、PayPal、支付宝、西联汇款 以最贵的洛杉矶机器为例,配置表如...

快快云:香港沙田CN2/美国Cera大宽带/日本CN2,三网直连CN2 GIA云服务器和独立服务器

快快云怎么样?快快云是一家成立于2021年的主机服务商,致力于为用户提供高性价比稳定快速的主机托管服务,快快云目前提供有香港云服务器、美国云服务器、日本云服务器、香港独立服务器、美国独立服务器,日本独立服务器。快快云专注为个人开发者用户,中小型,大型企业用户提供一站式核心网络云端服务部署,促使用户云端部署化简为零,轻松快捷运用云计算!多年云计算领域服务经验,遍布亚太地区的海量节点为业务推进提供强大...

hosthatch:14个数据中心15美元/年

hosthatch在做美国独立日促销,可能你会说这操作是不是晚了一个月?对,为了准备资源等,他们拖延到现在才有空,这次是针对自己全球14个数据中心的VPS。提前示警:各个数据中心的网络没有一个是针对中国直连的,都会绕道而且ping值比较高,想买的考虑清楚再说!官方网站:https://hosthatch.com所有VPS都基于KVM虚拟,支持PayPal在内的多种付款方式!芝加哥(大硬盘)VPS5...

notifyall为你推荐
股价图给你一张股票图你是怎么分析的具体的说svn服务器搭建如何在本机搭建SVN服务器oa办公系统下载免费oa办公软件哪里可以下载到?拜托各位大神国产操作系统下载国产操作系统要钱吗印度尼西亚国家代码谁知道世界各国的国家电话代码?印度尼西亚国家代码手机上的国家代码是什么印度尼西亚国家代码印尼身份证号的编码规则是什么?(比如中国的1-6位是地址代码,7-14位是出生日期码等)印度尼西亚国家代码国际代码熊猫烧香病毒下载熊猫烧香病毒?微软操作系统下载怎样在微软官网下载windows7 64位旗舰版
安徽双线服务器租用 godaddy域名解析 sugarhosts 便宜服务器 awardspace 优惠码 godaddy域名转出 xen 工作站服务器 中国电信测速网 1美金 Updog 阿里云官方网站 深圳域名 电信宽带测速软件 杭州电信宽带 广东服务器托管 服务器托管价格 cc加速器 德国代理 更多