如何等待并通知工作?

时间:2013-07-02 07:02:08

标签: java multithreading

我需要知道wait()和notify()是如何工作的?我无法通过使用wait()和notify()来实现其工作。相反,如果我使用while()循环进行等待,它可以正常工作。怎么回事?为什么我不能简单地使用wait()和notify()?

3 个答案:

答案 0 :(得分:4)

您是否阅读了wait - notify函数的文档?

无论如何,为了实现等待通知机制的最佳方式,使用类似的东西(基于this website):

public class WaitNotifier {
    private final Object monitoredObject = new Object();
    private boolean wasSignalled = false;

    /**
     * waits till another thread has called doNotify (or if this thread was interrupted), or don't if was already
     * notified before
     */
    public void doWait() {
        synchronized (monitoredObject) {
            while (!wasSignalled) {
                try {
                    monitoredObject.wait();
                } catch (final InterruptedException e) {
                    break;
                }
            }
            wasSignalled = false;
        }
    }

    /**
     * notifies the waiting thread . will notify it even if it's not waiting yet
     */
    public void doNotify() {
        synchronized (monitoredObject) {
            wasSignalled = true;
            monitoredObject.notify();
        }
    }

}

请注意,此类的每个实例只应使用一次,因此如果需要多次使用它,可能需要更改它。

答案 1 :(得分:3)

wait()和notify()在synchronized块中使用,同时使用线程暂停并从中断处继续。

等待立即失去锁定,而Nofity只会在遇到结束括号时离开锁定。

您还可以参考此示例示例:

public class MyThread implements Runnable {

    public synchronized void waitTest() {
        System.out.println("Before Wait");
        wait();
        System.out.println("After Wait");
    }

    public synchronized void notifyTest() {
        System.out.println("Before Notify");
        notify();
        System.out.println("After Notify");
    }
}


public class Test {

    public static  void main(String[] args) {
        Thread t = new Thread(new MyThread());
        t.start();    
    }
}

答案 2 :(得分:0)

我想您是在问为什么它与while循环一起使用而并非没有。 答案是当您的程序调用 wait()时,操作系统将挂起您的线程并激活(启动)另一个线程,这将发生所谓的 context switch 。线程需要保存有关您线程的一些“元数据” 以便以后能够恢复该线程,PC寄存器将回答您的问题。基本上PC(程序计数器)是指向继续执行后,线程应使用或将要执行的下一条指令是线程使用它来了解OS挂起该指令时要执行的指令,并继续执行该指令(在这种情况下,如果要查看它是通过Java程序实现的,下一条指令将是调用 wait())后的下一行。如《 Java并发实践》

中所述>
Every call to wait is implicitly associated with a specific condition predicate. When calling wait regarding a particular
condition predicate, the caller must already hold the lock associated with the condition queue, and that lock must also
guard the state variables from which the condition predicate is composed.

因为您的线程等待是因为在返回到被挂起的方法后未满足某些条件(应该是),因此需要重新检查该条件以查看是否已满足。满足条件将不再 wait ,如果不满足,它将再次调用 wait()(因为它在while循环中)。要知道的重要一点是

  1. PC(程序计数器)概念 和
  2. 事实上,在您的方法上调用 wait()的线程不会退出该方法->等待->重新恢复->再次调用该方法,而是等待->重新恢复->从被暂停的点(指令/行)继续(称为wait())