1
class Test {

    public static void main(String[] args) {

        System.out.println("1.. ");
        synchronized (args) {

            System.out.println("2..");

            try {
                Thread.currentThread().wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.println("3..");
        }

    }
}

I am getting IllegalMonitorStateException monitor exception in this code. As per my understanding, because of synchronized block around args which is string array object, current thread must have acquired the lock and with the wait method, I am release the lock.

Can someone explain me the reason behind this exception?

4

3 回答 3

4

你在wait()打电话Thread.currentThread()。在调用wait()任何对象之前,您必须拥有该对象的监视器,方法是在该对象上同步一个同步块。所以缺少的是

synchronized(Thread.currentThread()) {
    Thread.currentThread().wait();
}

也就是说,调用wait()Thread 对象不是您应该做的事情,并且可能表明您还没有理解做什么wait(),特别是考虑到您没有任何其他线程调用notify()notifyAll(). 同步传递给 main 方法的参数也是一个非常奇怪的选择。wait()是一种非常低级的方法,即使您完全了解它的作用,也应该很少使用。为了获得更好的答案,您应该解释您实际希望此代码做什么。

于 2013-07-07T14:59:37.530 回答
3

IllegalMonitorStateException 文档

抛出以指示线程已尝试在对象的监视器上等待,或通知其他线程在对象的监视器上等待而不拥有指定的监视器

Object#notify() 文档

线程通过以下三种方式之一成为对象监视器的所有者:

  • 通过执行该对象的同步实例方法。
  • 通过执行在对象上同步的同步语句的主体
  • 对于 Class 类型的对象,通过执行该类的同步静态方法。

因此,由于线程正在args对象上执行块同步

synchronized (args) {
    //...
}

你应该args.wait()打电话Thread.currentThread().wait();

于 2013-07-07T15:01:22.653 回答
0

嗨 ankit 我假设您正在尝试学习多线程的一些基本概念。尝试获取一些好的在线教程:http ://www.javaworld.com/jw-04-1996/jw-04-threads.html

或尝试一些基本的好书。http://www.amazon.com/SCJP-Certified-Programmer-Java-310-065/dp/0071591060/

您编写的程序实际上不需要同步,因为只有一个线程(主线程)。我知道您只是在尝试动手,因此提供了一些见解。即使您在 args(args.wait()) 上正确调用了 wait 方法或在 Thread.currentThread 上进行了同步,您的线程也可能会进入无限期等待(使您的程序无响应),因为没有其他线程来通知您的主线程。

于 2013-07-07T15:40:59.037 回答