IllegalMonitorStateException发生在线程未持有对象锁时调用wait/notify方法,正确做法是在synchronized块中调用并配合while循环检查条件,优先使用java.util.concurrent工具类简化并发控制。

在Java多线程编程中,IllegalMonitorStateException 是一个常见的运行时异常,通常发生在调用 wait()、notify() 或 notifyAll() 方法时线程未持有对象的监视器锁。理解其触发原因并掌握正确的处理方式,是编写稳定并发程序的关键。
理解IllegalMonitorStateException的根本原因
这个异常的核心原因是:线程在没有获取目标对象的内置锁(即synchronized锁)的情况下,尝试调用该对象的 wait()、notify() 或 notifyAll() 方法。
例如以下代码会抛出异常:
new Thread(() -> {
someObject.wait(); // 未持有锁,直接抛出IllegalMonitorStateException
}).start();
正确做法是确保这些方法必须在 synchronized 块或方法中被调用:
立即学习“Java免费学习笔记(深入)”;
synchronized (someObject) {
someObject.wait(); // 正确:已持有锁
}
使用synchronized确保锁的持有
调用 wait/notify 系列方法前,必须通过 synchronized 获取对象锁。这是最基础也是最重要的预防措施。
如果方法需要等待条件,应将整个同步逻辑包裹在 synchronized 块中 避免在 synchronized 外部调用 wait,即使之前进入过 synchronized 块也不行,因为锁可能已被释放 多个线程操作同一共享资源时,所有涉及 wait/notify 的代码都应使用同一把锁对象
配合while循环使用wait避免虚假唤醒
即使正确持有锁,也应始终在 while 循环中调用 wait(),而不是 if 条件判断。
操作系统或JVM可能在没有 notify 的情况下唤醒线程(称为虚假唤醒),因此需要重新检查条件:
synchronized (lock) {
while (!conditionMet) {
lock.wait();
}
// 执行条件满足后的操作
}
这样可以确保只有在真正满足条件时才继续执行。
优先考虑高级并发工具替代原始wait/notify
在现代Java开发中,建议使用 java.util.concurrent 包中的工具类来减少手动管理锁和条件的复杂性。
BlockingQueue:如 ArrayBlockingQueue、LinkedBlockingQueue,适用于生产者-消费者场景 CountDownLatch:用于等待一组操作完成 CyclicBarrier:让多个线程互相等待至某一点再继续 ReentrantLock + Condition:提供比 synchronized 更灵活的等待/通知机制
这些工具内部已正确处理了锁与等待逻辑,能有效避免 IllegalMonitorStateException 的发生。
基本上就这些。关键是理解 wait/notify 必须在 synchronized 上下文中执行,并尽量使用更高层次的并发结构来简化控制流程。不复杂但容易忽略细节。
以上就是Java中处理IllegalMonitorStateException技巧的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/44383.html
微信扫一扫
支付宝扫一扫