IllegalMonitorStateException异常,我们先看下API的定义:
/**
* Thrown to indicate that a thread has attempted to wait on an
* object's monitor or to notify other threads waiting on an object's
* monitor without owning the specified monitor.
*
* @author unascribed
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
* @see java.lang.Object#wait()
* @see java.lang.Object#wait(long)
* @see java.lang.Object#wait(long, int)
* @since JDK1.0
*/
public class IllegalMonitorStateException extends RuntimeException
大致意思就是说抛出这个异常表明线程尝试等待一个对象的监视器或者去通知其他正在等待这个对象监视器的线程时,但是没有拥有这个监视器的所有权。
monitor翻译成监视器,可能大家会有些疑惑。我们可以换一个角度来解释这个问题,大家都知道Java中每个类和对象都有一个同步锁,只有获取到调用同步锁,调用wait和notify方法才行(下一篇专门讲一下Java的锁)。下面我们看几个例子就明白是怎么回事了:
实例1:
调用所属对象的wait和notify方法。
//所属对象的情况
public synchronized void notifySlef(){
this.notify();
}
或
public synchronized void waitSlef(){
this.wait();
}
//其他对象的情况
public Object lock = new Object();
public synchronized void notifySlef(){
synchronized(lock) {
lock.notify();
}
}
或
public Object lock = new Object();
public synchronized void waitSlef(){
synchronized(lock) {
lock.wait();
}
}
因为在waitSlef和notifySlef方法使用了synchronized获取了所属对象或其他对象的同步锁,所以调用wait()或者notify()方法是不会报错的。
实例2:
调用类的notify和wait方法。
public static synchronized void notifyClass() {
Test.class.notify();
}
或者
public void waitClass() {
synchronized (Test.class) {
Test.class.wait();
}
}
调用类的wait和notify方法,就要获取到类的锁。
总之,我们可以把API中所说的监视器(monitor)理解成同步锁。想要执行某个对象的notify(), notifyAll(),wait(), wait(long), wait(long, int)方法
就必须获取该对象的锁,需要使用synchronized,不然就会抛出IllegalMonitorStateException异常。
分享到:
相关推荐
这就是为什么只有在同步的块或者方法中才能调用 wait/notify 等方法,否则会抛出 java.lang.IllegalMonitorStateException 异常的原因。 在 Java 1.5 之后版本中,JVM 内置锁做了重大的优化,如锁粗化、锁消除、轻...
需要注意的是,wait()方法只能在同步块或同步方法中调用,否则将抛出java.lang.IllegalMonitorStateException异常。这是因为wait()方法需要在获得同步锁后才能调用,以确保线程的安全。 notify()方法 notify()方法...
这些异常大多数都是`java.lang.Throwable`的子类,例如`ArrayIndexOutOfBoundsException`和`NullPointerException`。开发者可以通过`try-catch-finally`语句块来捕获和处理这些异常,保证程序的健壮性。 Java的接口...
`java.lang.RuntimeException: Problem`是异常的信息,不会直接打印到控制台。 - **选项B**:错误。`run. java.lang.RuntimeException: Problem`虽然包含了`run.`,但是没有正确地表示出`End of method.`的输出顺序...
Sun Certified Programmer for the Java Platform, Standard ...这些知识点涵盖了Java多线程编程中的关键概念,包括线程生命周期、异常处理、死锁以及对象监视器的使用。掌握这些知识对于通过SCJP6认证考试至关重要。
java.lang.RuntimeException: Problem End of method.`:先输出“run.”和异常信息,然后输出“End of method.” **正确答案**:DE - **解析**:当线程`t`启动后,会执行`run()`方法中的代码。因此,“run.”会被...
通过这些解析,我们可以了解到Java多线程编程的一些基本概念和常见陷阱,例如如何处理异常、死锁的预防以及`synchronized`和`wait()/notify()`的正确使用方式等。对于准备SCJP认证考试的学习者来说,掌握这些知识点...
Java提供了两种主要的等待唤醒机制:`wait()`、`notify()`和`notifyAll()`,它们都是`java.lang.Object`类的方法。这些方法必须在同步块或同步方法中使用,以避免因非法访问而导致的错误。 1. `wait()`方法:当一个...
因此,正确答案是`D.Endofmethod.run.java.lang.RuntimeException:Problem`和`E.run.java.lang.RuntimeException:ProblemEndofmethod.`,表示主线程输出“Endofmethod.”,然后是异常信息,或者异常信息先于主线程的...
- 选项 **E** (`run.java.lang.RuntimeException:ProblemEndofmethod.`) 表示线程开始运行并输出“run.”,然后抛出异常,之后主线程继续执行并输出“Endofmethod”。 这个题目主要考察的是Java线程的执行顺序以及...
java.lang.RuntimeException: Problem"。 2. 死锁的理解与预防: 死锁是多线程编程中的一个关键问题,它发生在两个或多个线程相互等待对方释放资源而无法继续执行的情况。问题3中的选项A和F正确阐述了死锁的特性...
需要注意的是,wait() 方法必须放置在 synchronized 块中,否则会在程序 runtime 时抛出“java.lang.IllegalMonitorStateException”异常。 wait() 方法可以通过 notify 或者 notifyAll 或者指定睡眠时间来唤醒当前...
- 调用`wait()`方法前必须获取监视器锁,否则会抛出`IllegalMonitorStateException`异常。 ##### 7. `finalize()` - **方法签名**:`protected void finalize() throws Throwable;` - **功能**:在垃圾收集器确定...
这些方法必须在`synchronized`代码块或方法中调用,因为它们需要在持有对象锁的情况下执行,否则会抛出`java.lang.IllegalMonitorStateException`异常。 1. `wait()`:调用此方法的线程会释放它持有的对象锁,进入...
正确答案为:**DE**,即先输出`run.`,然后是异常信息`java.lang.RuntimeException: Problem`,最后是`End of method.`。 #### 示例二:死锁理解 - **选项A**:多个线程同时发生死锁是可能的。当多个线程互相等待...
- `run()`方法包含于`java.lang.Thread`中,是这个线程的功能,需要用户重写。 - `start()`方法用于启动线程,通常在其他地方(如`main()`函数)调用此方法,不需要用户重写。 - 直接调用`t1.run();`不会启动新的线程...
异常是`java.lang.Throwable`的子类,分为检查性异常(需要捕获或声明)和运行时异常(可选捕获)。`try-catch-finally`块用于处理异常,`throw`关键字用于手动抛出异常。 2. **接口与虚类**:Java接口类似于C++的...
- `Thread.sleep(millisecond)` 方法来自 `java.lang.Thread` 类,它使当前正在执行的线程暂停指定的毫秒数,并将线程的执行权交还给操作系统。 - 睡眠结束后,线程并不会自动恢复执行,而是需要等待系统的调度。 ...
- **选项D**:“End of method.”(表示主程序结束),“run.”(线程输出),以及“java.lang.RuntimeException: Problem”(异常信息)。这个选项正确地展示了程序的执行顺序:主线程先输出“End of method.”,...