java - 如何在 Java 中决定 wait() 的循环条件

标签 java multithreading wait notify

我正在理解 Java 中关于多线程的 wait(),并且根据文档,wait() 应该始终处于循环中。

我很难理解我们必须在循环中给出的条件是什么。通常,我见过:

synchornized(obj) {
    while(some_condition) {
         obj.wait();
    }
    // some other code
}

我很难理解在我们保留 wait() 的循环中使用的“条件”。

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

由于这是线程间通信并且我们需要同步,所以我很难确定我必须为这两个不同的线程在循环中保持 wait() 的条件是什么。

非常感谢任何关于如何破译这个(我们保持循环的条件)的线索。

最佳答案

在这里,也许这几行会把你推向正确的方向,作为我之前评论的后续。

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!");

    }

}

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

关于java - 如何在 Java 中决定 wait() 的循环条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30155655/

相关文章:

java - 如何在Project Reactor中正确使用Schedulers.single()?

java - 如何与已调用监听器的父线程通信?

java - Android - 等待 Volley 响应返回

c - child 收到 sigstop 后 wait() 不返回

java - 如何创建包含 100 个随机整数的一维数组并求平均值、标准差和方差?

java - POI - 同一张纸上的多个数据验证范围

java - jackson :将json的一些字段映射到类的内部字段

java - 使用 Commons Digester 如何将单个 xml 条目解析为对象中的多个字段?

android - 停止 Android 服务中的线程

c++ - 如何使用 boost::thread_group 使用多客户端服务器?