public class ThreadTest { public static void main(String[] args) { new Thread(new ThreadDemo()).start(); }
}class ThreadDemo implements Runnable {
private int i = 0; public synchronized void run() {
try {
ThreadTest.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println(Thread.currentThread().getName() + ":" + i); }
}上面的代码ThreadTest.class.wait();会报一个 Exception in thread "Thread-0" java.lang.IllegalMonitorStateException 的错误。1. 请问这个是为什么?
2. 在synchronized中的wait();方法应该怎么用? 我想实现比如ThreadTest.class.wait();这样的wait 
   然后再在另一个类里面使用 ThreadTest.class.notify();   为什么是不可行的?
3. 一般来说  使用wait();的最常见情况是什么?

解决方案 »

  1.   

    1,“public class IllegalMonitorStateExceptionextends RuntimeException抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。”
    因为wait必须拥有此对象监视器。单单为了代码编译通过可改为: 
    synchronized( ThreadTest.class ) {
                ThreadTest.class.wait(5000);
    }
    2,3,按照JDK的说法:等待应总是发生在循环中,如下面的示例: synchronized (obj) {
    while (<condition does not hold>)
    obj.wait(timeout);
    ... // Perform action appropriate to condition
         }参见:java.lang.Object
      

  2.   


    public class ThreadTest {    public static void main(String[] args) {        new Thread(new ThreadDemo()).start();    }
    }class ThreadDemo implements Runnable {
        private int i = 0;    public synchronized void run() {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }        System.out.println(Thread.currentThread().getName() + ":" + i);    }
    }
    只有让当前执行的线程放弃对象锁,让其它正在等待的线程先执行。
      

  3.   

    ------解决方案--------------------------------------------------------
    如果不正确地管理wait/notify调用,应用程序可能会抛出IllegalMonitorStateException,例如,若不拥有对象的锁标记,而试图用wait/notify协调共享对象资源,应用程序将抛出IllegalMonitorStateException。 IllegalMonitorStateException意味着一个或多个资源可能不再处于一致状态,表示程序出现了严重问题。由于IllegalMonitorStateException是RuntimeException类型,因此它可能中断产生异常的线程。
      

  4.   

    使用了错误的对象调用了wait
      

  5.   

    goooooooooooooooooooooood~~~~~加油~~呵呵
      

  6.   


    那如何才算是正确的对象调用wait? 怎么做请问
      

  7.   

    下面这样就对了  你synchronized的是this 却让什么什么class wait() 
    这个是肯定不可以的哇
    public class test1 { private static final test1 t = new test1(); public static void main(String[] args) { new Thread(new ThreadDemo(t)).start(); }
    }class ThreadDemo implements Runnable {
    private int i = 0;
    private test1 t = null; public ThreadDemo(test1 t) {
    this.t = t;
    } public void run() {
    synchronized (t) { try {
    t.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    } System.out.println(Thread.currentThread().getName() + ":" + i); }
    }
    }
      

  8.   

    synchronized的意义在于获得对象锁,如果这个方法是非静态的,好比楼主的例子,那么获得的就是这个Instance的对象锁,如果是静态方法,就必须获得这个Class对象的对象锁wait()方法的意义是释放当前持有的锁资源,楼主仔细看你的代码
    先由于synchronized获得了这个Class的一个Instance的对象锁
    第二步却用wait视图释放Class对象的锁,当然会报锁状态错误的异常即你获得的是new ThreadDemo()的Monitor
    但你试图释放的是ThreadDemo.class的Monitor
    简而言之就是new ThreadDemo()和ThreadDemo是两个Java对象,好好理解这一层才是关键对象锁即异常里提到的Monitor