文章目录
在使用
wait、notify和notifyAll
这几个方法进行线程通信的时候,jvm虚拟机报错了:
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
报这个错呢,大概率是因为你在使用
wait、notify和notifyAll
这三个方法的时候,没有对锁的对象使用synchronized关键字。
给出正确示例:
public class MainGLock {
static class IRunable implements Runnable{
@SneakyThrows
@Override
public void run() {
synchronized (obj) {
obj.wait();
}
while (true) {
Thread.sleep(1000);
System.out.println("运行中...");
}
}
}
static Object obj = new Object();
public static void main(String[] args) throws Exception {
Thread thread1 = new Thread(new IRunable());
thread1.setDaemon(false);
thread1.start();
Thread.sleep(2000);
synchronized (obj) {
obj.notify();
}
System.out.println("thread1 is notify");
}
}
可以看到,我在任何调用obj的
wait、notify和notifyAll
方法的前面,都使用了
synchronized (obj)
,这是为什么呢?
报错信息显示,“该线程非法使用了监视器monitor”
也就是当前线程没有monitor的权限
而我们知道,
synchronized
关键字底层是基于java消息头和monitor监视器,也即你对obj使用了synchronized,也就获取了监视器monitor的权限。
所以:
在任何使用wait、notify和notifyAll 方法的前面,记得先对加锁对象使用synchronized关键字