`

理解IllegalMonitorStateException异常的抛出原因

阅读更多
在学习中有时会出现wait()方法抛 IllegalMonitorStateException 的情况,查阅wait 方法的API时,对于 IllegalMonitorStateException 的说明如下:

引用
IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。


从网上找来一段,自己改了改想了想,不敢说绝对正确,但确是自己的心得和理解(若有不正确的地方,恳请各位大侠指正吧...)


以下代码抛IllegalMonitorStateException

class M018 
{
	public static void main(String[] args) throws Exception
	{
		M018 m18 = new M018();
		m18.one();
	}

	public void one() throws Exception
	{
		Object obj = new Object();
		synchronized (Thread.currentThread())
		{
			obj.wait();//当前线程是主线程(所有者是Object)
			//obj.notify();
		}
	}
}


/**
 *2010-3-26 下午23:30:59
 *Conclusion: 
 IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。 
 */

上例中,synchronized的对象是Thread.currentThread(),查阅currentThread()的说明如下:
引用
static Thread currentThread()
          返回对当前正在执行的线程对象的引用。


因为,Thread.currentThread()返回的当前线程的引用与当前线程,指向的是不同对象.

请看如下代码:
import static java.lang.System.out;
class M019 
{
	public static void main(String[] args) 
	{
		One o = new One();
		Thread o1 = new Thread(o);
		Thread o2 = o.getThread();
		//o1.start();//将此行注释去除,执行正常
		//o2.start();//将此行注释去除,抛IllegalMonitorStateException 
		if(o1==o2)
			out.println("equals");
		else
			out.println("Not equals");
		if(o1.equals(o2))
			out.println("equals");
		else
			out.println("Not equals");
	}
}

class One implements Runnable
{
	public void run()
	{
		for(int i = 0; i < 10 ; i++)
		{
			out.print(i+" ");
		}
	}

	public Thread getThread()
	{
		return Thread.currentThread();
	}
}

/**
 *2010-3-26 下午23:58:59
 *Conclusion: 
 */


1.比较引用与equals方法都将返回Not equals
2.在上例中,之所以没有重写equals方法的原因是,Object对equals方法的定义如下:
    public boolean equals(Object obj) {
	return (this == obj);


所以没有必要重写.


以下代码进入wait状态,退出时按Ctrl+c,但是不抛IllegalMonitorStateException异常.
//
import static java.lang.System.out;
class M018 
{
	public static void main(String[] args) throws Exception
	{
		M018 m18 = new M018();
			m18.one(m18);
			//System.out.println("Hello World!");
	}

	public void one(M018 n) throws Exception
	{
		Object obj = new Object();
		synchronized (this)
		{
			n.wait();
		}
	}
}


/**
 *2010-3-26 下午23:30:59
 *Conclusion: 
 IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。 
 */



总结如下:
非当前线程的引用调用wait方法,抛IllegalMonitorStateException异常
0
1
分享到:
评论

相关推荐

    java异常(pdf格式)

    3. **异常的声明**:当一个方法可能会抛出异常,但不想在该方法内部处理时,可以通过在方法签名中声明抛出异常的方式来告诉调用者需要处理这些异常。 #### 五、常见异常类型 1. **运行时异常**: - `Arithmetic...

    310-065.pdf

    #### 异常抛出解析 - **选项B**:`IllegalMonitorStateException`。当线程尝试在不拥有监视器锁的情况下调用`wait()`或`notify()`时,将抛出此异常。在这个例子中,`obj.wait()`在没有持有`obj`对象锁的情况下被调用...

    ocjp 考试题库 300题

    因此,正确的答案是B,因为代码试图在一个非对象的Thread实例上调用wait()和notify(),这是非法的,并会抛出IllegalMonitorStateException异常。这里考查的是对Java线程和同步机制的理解,特别是对锁对象的理解和...

    scjp认证考试原题

    - B正确,因为`obj.wait()`是在`Thread.currentThread()`上同步而不是`obj`,因此如果当前线程不是`obj`的对象锁的所有者,将会抛出`IllegalMonitorStateException`。 - C错误,`TimeoutException`不是Java标准...

    很不错的SJCP题库

    正确的答案是这个代码可能会抛出IllegalMonitorStateException,这是因为wait()和notify()方法只能在同步上下文中被调用,也就是被synchronized关键字修饰的块中。这就强调了在Java中,正确使用synchronized关键字...

    killtest的scjp6.0最新题库

    - 选项 **B** 表示这段代码可以抛出`IllegalMonitorStateException`异常,这是因为在`wait()`之前没有首先调用`synchronized`来获取`obj`对象的监视器锁,导致了非法的监视器状态。 该题目考察了Java中的同步机制,...

    scjp考试真题(含答案)

    选项D和E正确地描述了这种情况,即"End of method."在异常抛出之后打印,因为`main`方法的剩余部分会继续执行。 **问题二**: 此题关注的是死锁(Deadlock)的概念。死锁是指两个或多个线程相互等待对方释放资源,...

    SCJP 1.6 10年5月最新真题

    如果在`run()`方法中抛出了一个异常,则该线程将停止执行,并且主线程会继续执行。因此,在此例子中,`run.`会在异常之前打印,而`End of method.`会在异常之后打印。 - **选项A**:错误。`java.lang....

    Sun Certified Programmer for the Java 2 Platform(310-065)

    如果对象的监视器没有被正确持有(即当前线程未拥有该对象的锁),代码可能会抛出IllegalMonitorStateException。因此,B选项正确。A选项也是正确的,因为wait()可以因中断而抛出InterruptedException。C选项不正确...

    SCJP(310-065)考试参考题集1

    正确答案是B(代码可以抛出IllegalMonitorStateException)。如果wait()和notify()的顺序颠倒,方法将无法正常完成,因为wait()会导致当前线程释放对监视器对象的持有,使得notify()无效。E选项正确,因为另一个线程...

    OCJP 真题 2016最新版,包过

    - B:这段代码可以抛出 `IllegalMonitorStateException`,因为在没有获得对象监视器的情况下调用 `wait()` 方法会抛出此异常。由于 `obj.wait()` 的调用发生在 `Thread.currentThread()` 的同步块内,而并非在 `obj`...

    java开发面试题文思

    Java异常处理是一种用于管理程序运行时错误的机制,包括捕获异常、抛出异常和处理异常。 - **自定义异常**:可以通过继承`Exception`或其子类来创建自定义异常类。 - **异常分类**: - 运行时异常(`...

    sleep()、wait()、yield()和join()方法特点及区别.docx

    4. **异常处理**:`sleep()`方法需要捕获`InterruptedException`,而`wait()`方法不需要捕获异常,但是当`wait()`不在同步环境中调用时,会抛出`IllegalMonitorStateException`,这是一个运行时异常,不需要显式捕获...

    ORACLE认证考试ocjp题库(覆盖率99%)本人刚考完

    - 由于 `obj` 并不是同步块的对象,因此调用 `obj.wait()` 时会抛出 `IllegalMonitorStateException`。 - 其他选项: - A. This code can throw an InterruptedException. - `obj.wait()` 本身可以抛出 `...

    金蝶中间件2011校招笔试题

    当程序运行时,会抛出`IllegalMonitorStateException`,因为调用`wait()`的线程并没有持有对象的锁。选项A、B、D和E都不正确,因为它们没有考虑到异常处理。选项C是正确的,因为它指出程序会编译并打印"FINALLY",...

    SCJP6 英文版

    根据提供的信息,我们可以总结出以下...正确答案为:**B**,即这段代码可以抛出`IllegalMonitorStateException`。 以上分析涵盖了给定内容中的核心知识点,包括多线程编程的基础、异常处理、以及关于死锁的重要概念。

Global site tag (gtag.js) - Google Analytics