Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 程序停止:wait()和notify()_Java_Multithreading_Wait_Synchronized_Notify - Fatal编程技术网

Java 程序停止:wait()和notify()

Java 程序停止:wait()和notify(),java,multithreading,wait,synchronized,notify,Java,Multithreading,Wait,Synchronized,Notify,我试图做到这一点:创建两个不同的线程,一个打印奇数,一个打印偶数。一旦一个线程打印出一个数字,它就必须等待另一个线程,以此类推,这是一个接一个的 为了实现这一点,我将使用synchronized block以及wait()和notify() 我正在创建一个类,该类的对象将用于传递给两个线程中的同步块 代码如下: -->这是将传递给同步块的已使用对象 package com.vipin.multithread.variousdemos; public class SyncObject {

我试图做到这一点:创建两个不同的线程,一个打印奇数,一个打印偶数。一旦一个线程打印出一个数字,它就必须等待另一个线程,以此类推,这是一个接一个的

为了实现这一点,我将使用synchronized block以及wait()和notify()

我正在创建一个类,该类的对象将用于传递给两个线程中的同步块

代码如下: -->这是将传递给同步块的已使用对象

package com.vipin.multithread.variousdemos;

    public class SyncObject {

        public SyncObject () {  

        }
}
奇数螺纹: 偶数线程:更新 --->如代码所示,我创建了两个线程来打印偶数和奇数。我正在使用synchronized块,并传递类型==>SyncObject的对象

SyncObject作为参数传递给main中的这些不同线程

但是,此程序会停止,即仅执行第一条语句,然后它将永远等待:

以下是输出: 奇数为-->1

主线程中 偶数为-->2

我无法理解为什么这个程序会一直等待,我使用的是我们调用synchronized()、wait()和notify()的同一个对象。根据我的理解,它应该是有效的,但不确定为什么不起作用

任何关于这件事为什么永远都在等待的线索

更新: 我对代码做了一些修改,更新后效果很好

我仍然有些怀疑。即使没有锁定监视器,线程也会调用notify(),就像我更新代码后的情况一样

事件顺序:


首先执行奇数线程,然后调用wait()这里的问题只是两个线程直接进入等待。线程1获取
所以
,打印值然后等待。线程2然后获取
,然后打印值并等待。所以两人都睡不着,因为没有人通知他们。因此,一个简单的修复方法是在
So.wait()
之前执行
So.notify()
。那他们就不会无限期地等待了

编辑

奇数线程启动、执行并等待。然后,即使是线程也会启动、执行、通知&然后等待。即使是线程也会在监视器上保持锁,直到它进入等待状态

当偶数线程调用notify时,奇数线程唤醒并轮询锁。一旦偶数线程进入等待状态(&释放锁),则奇数线程可以获得锁

如果偶数线程没有调用notify,那么奇数线程将继续休眠。偶数线程将等待并释放锁。没有线程轮询或试图获取锁,因此程序保持挂起状态


报告也提供了类似的解释。我希望这能消除你的疑虑

+1。不要忘记在
OddThread
中添加
if(index>=5){so.notify();return;}
,以唤醒
EvenThread
。根据文档,wait()解锁监视器,然后停止调用它的线程的执行。这是基于我已经编码的。考虑,首先执行ODWTHOST,然后调用WAITE(),此时它将解锁监视器并停止执行,然后将执行线程,并在EngaveWAIT()上解锁监视器并停止执行。那么,在什么地方我们必须调用notify()。使用此模型,则我们没有任何机会通知()。我见过等待()的代码。。通知();其他线程也在等待()。。通知()。。我不知道我错过了什么!是的,wait()表示解锁监视器并停止执行。但是,这并不意味着其他线程开始执行。它们也处于“暂停”模式。Notify()告诉他们立即重新开始执行。通常,程序是在wait()语句最先出现的地方编写的,然后是notify(),然而,在执行时,您会发现一个线程进入wait(),而另一个线程跳过它&继续进入notify()。Wait()语句通常在某些条件下。谢谢@VineetRamachandran!我已经更新了问题,请看一看,我对notify()的行为w.r.t monitor/lock有疑问。1)在检查是否有需要等待的内容之前,不要调用
wait
。2) 在某个地方,您必须存储您正在等待的东西,即下一个线程应该是哪个线程。没有它,线程就无法知道它是否应该等待,或者它是否应该工作。
package com.vipin.multithread.variousdemos;

public class OddThread implements Runnable {

private Thread t;
int index=0;
SyncObject so=null;

int odd_nums[] = {1,3,5,7,9};

public OddThread(SyncObject so) {
    t = new Thread(this,"Odd Thread");
    this.so = so;
    t.start();
}

public Thread getThreadInstance() {
    return t;
}

@Override
public void run() {
    while (true) {
        synchronized(so) {
            System.out.println("Odd num is --->" + odd_nums[index]);
            try {
                so.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            index++;
            so.notify();
            if(index>=5) {
                return;
            }
        }
    }
}
}
package com.vipin.multithread.variousdemos;

public class EvenThread implements Runnable {

private Thread t;
int index=0;
SyncObject so=null;

int even_nums[] = {2,4,6,8,10};

public EvenThread(SyncObject so) {
    t = new Thread(this, "Even thread");
    this.so = so;
    t.start();
}

public Thread getThreadInstance() {
    return t;
}

@Override
public void run() {
    while(true) {   
        synchronized(so) {
            System.out.println("Even num is --->" + even_nums[index]);
            so.notify(); <-- Here we are notifying.
            try {
                so.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            index++;
            //so.notify(); <-- commented out.
            if(index>=5) {
                break;
            }
        }
    }
}
}
package com.vipin.multithread.variousdemos;

public class EvenOddDemo {

public static void main(String[] args) throws InterruptedException {
    SyncObject so = new SyncObject();

    OddThread ot = new OddThread(so);
    EvenThread et = new EvenThread(so);

    System.out.println("\nIn main thread");

    Thread.sleep(1000000000);

    System.out.println("Exiting main thread...");
}
}