必须在 synchronized 块中调用 wait/notify,否则抛 IllegalMonitorStateException;推荐优先使用 BlockingQueue 或 Condition 替代手写 wait/notify。
wait/notify 必须在 synchronized 块中调用
直接调用 wait() 或 notify() 会抛出 IllegalMonitorStateException,因为这两个方法依赖当前线程持有对象的监视器锁。JVM 要求调用前必须已通过 synchronized 获取该对象锁。
- 错误写法:
obj.wait();(未加锁)→ 立即崩溃 - 正确写法:
synchronized(obj) { obj.wait(); } -
wait()会释放锁并挂起线程;notify()不释放锁,只唤醒一个等待线程 - 用
notifyAll()更安全,避免因条件判断不一致导致的“假死”(如多个生产者/消费者共用同一锁)
用 Condition 替代 wait/notify 实现更清晰的等待队列
Condition 是 java.util.concurrent.locks 包提供的替代方案,配合 ReentrantLock 使用,能为不同等待逻辑创建独立的等待队列,避免 notify() 唤醒错类型线程的问题。
- 一个
ReentrantLock可关联多个Condition:比如notFull和notEmpty -
condition.await()类似wait(),但需在lock.lock()/lock.unlock()块内 - 唤醒指定队列:
notFull.signal()不会影响notEmpty上等待的线程 - 注意:不能混用
synchronized+Condition,否则抛IllegalMonitorStateException
volatile 不足以实现线程间通信,仅适合简单状态通知
volatile 能保证变量读写的可见性与有序性,但无法保证原子性。它适用于「一个线程改、多个线程读」的轻量级信号场景(如开关标志),但不能替代同步机制来协调共享资源访问。