java for wait()方法的异常

时间:2015-12-22 11:20:15

标签: java

public class Bees {
    public static void main(String[] args) {
        try {
            new Bees().go();
        } catch (Exception e) {
            System.out.println("thrown to main" + e);
        }
    }

    synchronized void go() throws InterruptedException {
        Thread t1 = new Thread();
        t1.start();
        System.out.print("1 ");
        t1.wait(5000);
        System.out.print("2 ");
    }
}

本程序的输出是:

1 thrown to main

我不明白为什么thrown to main来到这里。

2 个答案:

答案 0 :(得分:5)

您收到java.lang.IllegalMonitorStateException,因为您在wait()上调用的对象t1不拥有同步锁。

请注意,当您将方法声明为synchronized时,该方法的锁定所有者是当前对象(在这种情况下,您的Bees实例)。如果您想在wait()上致电t1,则需要在t1上进行同步:

...
    Thread t1 = new Thread();
    synchronized(t1) {
        t1.start();
        System.out.print("1 ");
        t1.wait(5000);
    }
...

另外,在捕获异常时,应始终将异常本身包含在日志输出中,至少要像

一样
...
} catch (Exception e) {
   System.out.println("thrown to main" + e);
}
...

否则您可能会错过重要信息(例如实际引发的异常)。

另见The Java™ Tutorials: Synchronization.

答案 1 :(得分:2)

您需要从wait块内调用synchronized。当前线程应该在等待之前获取对象的监视器。

JavaDoc复制:

  

当前线程必须拥有此对象的监视器。线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。然后该线程等待,直到它可以重新获得监视器的所有权并继续执行。

synchronized (obj) {
     while (<condition does not hold>)
         obj.wait();
     ... // Perform action appropriate to condition
 }