一个关于notify和notifyAll的问题

问题描述

程序不写了,我复述一下吧:程序是要用多线程完成0和1在控制台上的交替输出一个类里,我定义两个方法,一个加一,一个减一。加和减里,我都做了判断,用到了wait()方法和notify;之后定义了两个Thread的继承类,一个run()了加一,一个run()了减一。最后,main方法里,我new了一个含有加一和减一的类,然后start了两个Tread类。结果完成了0和1的替换。但是只要超过了2个线程,结果就会出现问题。原因是加一和减一方法中判断是否wait是用了if,应该改成while;改完之后,还要将notify改成notifyAll。今天发现了另外一个方法,好神奇:不用改notify就是在Thread类的run方法中设置一个sleep,让此线程睡上1秒,效果和notifyAll一样。这里注意一下,我的Thread类中run类是用了for的,循环了20次,如果不改notify,0和1出现几次,程序就卡在那里了,想必是notify唤醒wait之后,wait遇到while,死循环在哪里了,但是还是想不通,为什么用了sleep之后,notify就能准确的唤醒正确的线程呢。

解决方案

解决方案二:
你关键的代码也要贴点,要不谁知道你的错误发生在哪?你明白notify和notifyAll的区别,也就基本明白了为啥这样;notify选择是任意性的,所以当线程大于2时,若唤醒的线程不具备条件时又会wait,这样所有的线程都在wait,就是你说的程序就卡在那里了;而notifyAll会唤醒在此对象监视器上等待的所有线程,也就是说总有一个线程会满足你的if或while条件,因此总会有一个线程会继续运行,并nofityAll,所以程序没问题;虽然不知道你把sleep放在哪里,既然没问题,我想你的sleep放在if或while条件之后,但还没有引起其它线程的if或while条件满足,当这个线程sleep1秒,对于CPU来说,足以让所有的其它线程都调用run方法,也就是其它线程都会进入wait了;当你这个线程再次运行时,notify哪个线程都会唤醒其中一个了;

时间: 2024-11-05 18:38:29

一个关于notify和notifyAll的问题的相关文章

Java notify和notifyAll的区别和相同_java

经常在往上逛,关于在java中notify和notifyAll,经常有人有以下的说法: notify只会通知一个在等待的对象,而notifyAll会通知所有在等待的对象,并且所有对象都会继续运行 并且,好像都有例子可以证明.上面的说法,可以说对,也可以说不对.究其原因,在于其中有一点很关键,官方的说法如下所示: wait,notify,notifyAll: 此方法只应由作为此对象监视器的所有者的线程来调用.通过以下三种方法之一,线程可以成为此对象监视器的所有者 : 通过执行此对象的同步实例方法.

Java的wait(), notify()和notifyAll()使用心得(转)

  本篇文章是对java的 wait(),notify(),notifyAll()进行了详细的分析介绍,需要的朋友参考下wait(),notify()和notifyAll()都是java.lang.Object的方法:wait(): Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.notify()

如何在 Java 中正确使用 wait, notify 和 notifyAll – 以生产者消费者模型为例

wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait.notify 和 notifyAll 来实现线程间的通信..举个例子,如果你的Java程序中有两个线程--即生产者和消费者,那么生产者可以通知消费者,让消费者开始消耗数据,因为队列缓冲区中有内容待消费(不为空).相应的,消费者可以通知生产者可以开始生成更多的数据,因为当它消耗掉某些数据后缓冲区不再

线程间协作的两种方式:wait、notify、notifyAll和Condition

在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权.因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去.因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用权,并进入挂起状态.然后等待消费者消费了商品,然后消费者通知生产者队列有空间了.同样地,当

java-并发-线程间协作的两种方式:wait、notify、notifyAll和Condition

线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权.因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去.因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用权,并进入挂起状态.然后等待消费者消费了商品,然后消费者通知生产者队列有空间了.同样地,当队列空时,消费者也必须等待,等待生产者通知它队列中有

基于Java多线程notify与notifyall的区别分析_java

当一个线程进入wait之后,就必须等其他线程notify/notifyall,使用notifyall,可以唤醒所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一个.注意,任何时候只有一个线程可以获得锁,也就是说只有一个线程可以运行synchronized 中的代码,notifyall只是让处于wait的线程重新拥有锁的争夺权,但是只会有一个获得锁并执行. 那么notify和notifyall在效果上又什么实质区别呢?主要的效果区别是notify用得不好容易导致死锁,

Java的wait(), notify()和notifyAll()使用心得_java

wait(),notify()和notifyAll()都是java.lang.Object的方法:wait(): Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.notify(): Wakes up a single thread that is waiting on this object's

通过两个小栗子来说说Java的sleep、wait、notify、notifyAll的用法

线程是计算程序运行的最小载体,由于单个单核CPU的硬件水平发展到了一定的瓶颈期,因此就出现了多核多CPU的情况,直接就导致程序员多线程编程的复杂.由此可见线程对于高性能开发的重要性. 那么线程在计算机中有好几种状态,他们之间是怎么切换的?sleep和wait又有什么区别?notify和notifyAll怎么用?带着这些问题,我们来看看Java的线程吧! Thread的状态 先来看看Thread类里面都有哪几种状态,在Thread.class中可以找到这个枚举,它定义了线程的相关状态: publi

Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期

1.问题的引出 class MyThread implements Runnable{ private int ticket = 5 ; // 假设一共有5张票 public void run(){ for(int i=0;i<100;i++){ if(ticket>0){ // 还有票 try{ Thread.sleep(300) ; // 加入延迟 }catch(InterruptedException e){ e.printStackTrace() ; } System.out.prin