Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.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

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()的循环条件_Java_Multithreading_Wait_Notify - Fatal编程技术网

如何确定Java中wait()的循环条件

如何确定Java中wait()的循环条件,java,multithreading,wait,notify,Java,Multithreading,Wait,Notify,我理解Java中的wait()是关于多线程的,根据文档,wait()应该总是在一个循环中 我很难理解在循环中我们必须给出什么条件。通常,我看到: synchornized(obj) { while(some_condition) { obj.wait(); } // some other code } 我很难理解我们保持等待()的循环中使用的“条件” 我试图实现一个场景,在这个场景中,我创建了两个不同的线程(两个实现Runnable接口的不同类),用于

我理解Java中的wait()是关于多线程的,根据文档,wait()应该总是在一个循环中

我很难理解在循环中我们必须给出什么条件。通常,我看到:

synchornized(obj) {
    while(some_condition) {
         obj.wait();
    }
    // some other code
}
我很难理解我们保持等待()的循环中使用的“条件”

我试图实现一个场景,在这个场景中,我创建了两个不同的线程(两个实现Runnable接口的不同类),用于打印奇数和偶数,如:1、2、3、4、5、6

因为这是线程间的通信,我们需要同步,所以我很难将这两个不同线程在循环中保持wait()的条件联系起来


对于如何破译这个(我们在循环中保持的条件)的任何线索,我们都非常感激。

循环条件应该检查执行(当前类的线程)是否需要暂时暂停

以著名的生产者消费者问题为例,生产者在哪里会看起来像

synchronized(mySharedObj)
{
while(mySharedObj.length==maxSize)
{
 mySharedObj.wait();
}
}

如果mySharedObj上有n个生产者线程,那么当共享资源(mySharedObj)达到极限时,所有线程都将等待。

这里,也许这几行将把您推向正确的方向,作为我之前评论的后续

class LastPrintedMonitor {
    public boolean wasLastEven = false;

}

class PrinterOdd implements Runnable {

    LastPrintedMonitor monitor;

    public PrinterOdd(LastPrintedMonitor monitor) {
        this.monitor = monitor;
    }

    @Override
    public void run() {
        for (int i = 2; i < 40; i += 2) {
            synchronized (monitor) {
                while (!monitor.wasLastEven) {
                    try {
                        monitor.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                System.out.println(i);
                monitor.wasLastEven = false;
                monitor.notifyAll();
            }
        }

    }

}

class PrinterEven implements Runnable {

    LastPrintedMonitor monitor;

    public PrinterEven(LastPrintedMonitor monitor) {
        this.monitor = monitor;
    }

    @Override
    public void run() {
        for (int i = 1; i < 40; i += 2) {
            synchronized (monitor) {
                while (monitor.wasLastEven) {
                    try {
                        monitor.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                System.out.println(i);
                monitor.wasLastEven = true;
                monitor.notifyAll();
            }
        }

    }

}

public class EvenOddPrinterDemo {

    public static void main(String[] args) {
        LastPrintedMonitor monitor = new LastPrintedMonitor();

        Thread odd = new Thread(new PrinterOdd(monitor));
        Thread even = new Thread(new PrinterEven(monitor));

        odd.start();
        even.start();

        try {
            odd.join();
            even.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Done!");

    }

}
class LastPrintedMonitor{
公共布尔值waslast偶数=false;
}
类PrinterOdd实现可运行{
最后打印的监视器监视器;
公共打印机添加(上次打印的监视器监视器){
this.monitor=监视器;
}
@凌驾
公开募捐{
对于(int i=2;i<40;i+=2){
同步(监视器){
而(!monitor.waslast偶数){
试一试{
monitor.wait();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
系统输出打印LN(i);
monitor.waslast偶数=false;
monitor.notifyAll();
}
}
}
}
类PrinterEven实现Runnable{
最后打印的监视器监视器;
公共打印机版本(上次打印的监视器){
this.monitor=监视器;
}
@凌驾
公开募捐{
对于(int i=1;i<40;i+=2){
同步(监视器){
while(monitor.waslast偶数){
试一试{
monitor.wait();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
系统输出打印LN(i);
monitor.waslast偶数=true;
monitor.notifyAll();
}
}
}
}
公共类EvenOddPrinterDemo{
公共静态void main(字符串[]args){
LastPrintedMonitor监视器=新的LastPrintedMonitor();
线程奇数=新线程(新打印机添加(监视器));
线程偶数=新线程(新打印机偶数(监视器));
奇。开始();
偶数。开始();
试一试{
奇数连接();
偶数。join();
}捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(“完成!”);
}
}

您提到了两个类,因此它们的同步方法不会相互同步。这就是我们在监视器上同步的原因,因为这两个对象必须共享一些东西才能让它们“听到”彼此的声音。

获取同步方法“lock”的线程有什么原因吗可能无法继续,并希望将密钥临时分发给另一个线程,该线程可能会更改某些内容,以便分发密钥的线程能够继续?如果是-这是你的情况。是的。首先想象打印奇数的线程,打印1;然后这个线程应该等到另一个线程打印偶数,以此类推。因为它们必须运行:奇数,偶数,奇数,偶数,奇数,偶数…所以这里是你的条件:最后一个打印的数字是奇数吗?布尔值最后一次打印可能很奇怪?所以,您只检查线程打印偶数,并等待该布尔值设置为true。这只能在线程打印奇数时完成。因此,当线程打印偶数首先获得处理器时间并获得方法时,仍然可以将其传递给偶数打印线程。太棒了!我在做一个类似的方法,但是我将整个逻辑保持在无限循环中(对于这两个不同的线程)。我很难“猜”出应该是什么情况。仅供参考,这是我的问题--->谢谢你对这一点的洞察,了解了jist的实际含义。谢谢你的帮助。