Java中的IllegalMonitorStateException
是在使用synchronized代码块或方法时抛出的一种异常,它表示当前线程试图等待、通知或唤醒另一个线程时,当前线程没有拥有此对象的监视器锁。下面是可能引发该异常的两个示例:
示例一:
public class Example {
public synchronized void methodA() {
System.out.println("methodA");
methodB();
}
public synchronized void methodB() {
System.out.println("methodB");
}
}
public class Main {
public static void main(String[] args) {
Example obj = new Example();
obj.methodA();
}
}
在上面的代码中,当methodA
被调用时,methodB
也被调用,但进入methodB
时已经释放了对象的监视器锁,因此在等待、通知或唤醒另一个线程时会抛出IllegalMonitorStateException
异常。
解决办法:要解决这种情况,需要使用同步块(synchronized block)而不是同步方法(synchronized method)。例如,我们可以修改methodA
和methodB
的代码如下:
public class Example {
public void methodA() {
System.out.println("methodA");
synchronized (this) {
methodB();
}
}
public void methodB() {
System.out.println("methodB");
}
}
public class Main {
public static void main(String[] args) {
Example obj = new Example();
obj.methodA();
}
}
示例二:
public class Example {
public void method() {
synchronized (this) {
wait();
}
}
}
public class Main {
public static void main(String[] args) {
Example obj = new Example();
obj.method();
}
}
在上面的代码中,wait
方法必须在同步块中调用,否则会抛出IllegalMonitorStateException
异常。
解决办法:我们需要确保在调用wait
方法之前获取对象的监视器锁。例如,我们可以修改method
方法的代码如下:
public class Example {
public void method() throws InterruptedException {
synchronized (this) {
wait();
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
Example obj = new Example();
synchronized (obj) {
obj.method();
}
}
}
在上面的代码中,我们获取Example
对象的监视器锁并在同步块中调用method
方法,这样就可以避免抛出IllegalMonitorStateException
异常。