调用Object类的wait()方法的异常

时间:2012-12-21 12:15:04

标签: java oop

以下代码即使在通知当前线程后也不会执行(使用此功能)。

public synchronized void test() {
    String str = new String();
    try {
        System.out.println("Test1");
        this.wait();
        this.notifyAll();
        System.out.println("Test2");
    } catch (Exception e) {
        // TODO Auto-generated catch block
        System.out.println("Inside exception");
        e.printStackTrace();
    }
 }

我在控制台上仅输出Test1

在第二种情况下,如果我在字符串对象上调用wait方法,我会得到异常。原因是因为字符串类对象str没有锁定当前对象。但我想知道str.wait()实际意味着什么?

public synchronized void test() {
    String str = "ABC";
    try {
        System.out.println("Test1");
        str.wait();
        str.notifyAll();
        System.out.println("Test2");
    } catch (Exception e) {
        // TODO Auto-generated catch block
        System.out.println("Ins");
        e.printStackTrace();
    }
 }

控制台输出:

> Test1  
java.lang.IllegalMonitorStateException

5 个答案:

答案 0 :(得分:7)

不确定您对该代码的期望:

  1. 在您的第一个示例中,wait执行了它所说的内容:它等待,因此永远不会调用notifyAll
  2. 在第二个示例中,如果不先保存该对象的监视器,则无法在对象上调用wait。所以你需要在synchronized(str)块中以避免异常。但是你仍然会遇到与1相同的问题。
  3. waitnotify的主要用例是线程间通信,即一个线程等待,另一个线程通知等待线程可以唤醒。在您的情况下,相同的线程位于通信通道的两端,但不起作用。

答案 1 :(得分:3)

你不应该在同一个帖子中一个接一个地调用waitnotify。它们应该从不同的线程执行。如果你等待某事,那么在该线程中控件不会更进一步,直到某个其他线程要通知它

答案 2 :(得分:3)

您应该学习如何正确使用wait()notify():来自Effective Java(Josh Bloch):

// The standard idiom for using the wait method
synchronized (obj) {
    while (<condition does not hold>)
    obj.wait(); // (Releases lock, and reacquires on wakeup)
    ... // Perform action appropriate to condition
}

这使当前线程正确等待条件变为true。当这个条件成立时,其他线程应该调用notify()notifyAll()

然而,Josh更重要的建议是:更喜欢并发实用程序等待并通知

答案 3 :(得分:0)

关于你的第一个案件: wait导致当前线程等待,直到另一个线程调用notify()方法或notifyAll()方法。因此,除非您在另一个线程中执行,否则将永远不会调用notify all。

答案 4 :(得分:0)

在您的第一个代码段中,当您致电wait时,该线程会排队等待该实例。 notifyAll未执行,因为胎面已经在等待。

通知需要在另一个步骤上执行。