为何在Java中调用notify方法必须持有对象锁?
Java中调用notify()必须持有锁的原因
Thread thread = new Thread(() -> { synchronized (this){ try { this.wait(); System.out.println("Woke"); } catch (InterruptedException e) { throw new RuntimeException(e); } } }); thread.start(); TimeUnit.SECONDS.sleep(1); this.notify();
调用上述代码中的notify()方法时,会抛出如下异常:
java.lang.IllegalMonitorStateException: current thread is not owner
notify()的典型用法是:调用它后,通过退出synchronized块隐式释放锁,让等待线程重新获取锁。
但上述代码在未持有锁时就调用了notify(),既然此时其他线程本可尝试获取锁,为何Java要求调用该方法必须持有锁?
核心原因主要有三点:
保证线程间的可见性
wait/notify机制本质是配合锁实现线程交互,而synchronized锁自带内存语义——持有锁的线程修改的变量会同步到主存,释放锁时其他线程能感知到这些修改。如果允许无锁调用notify,等待线程可能无法及时察觉触发通知的条件变化,引发逻辑异常。避免竞态条件与通知丢失
假设线程A检查某个条件后准备调用wait,但在它真正进入等待状态前,线程B未持有锁就调用了notify,此时线程A的wait会错过这次通知,陷入永久等待。只有持有锁,才能保证「检查条件→调用wait/notify」的操作是原子性的,从根源上避免这种竞态场景。维护锁机制的一致性
Java的内置同步机制围绕synchronized锁设计,wait/notify作为锁的配套等待通知工具,必须与锁绑定才能保证整个同步逻辑的一致性,降低开发者的理解和维护成本,减少误用概率。
内容的提问来源于stack exchange,提问作者Name Null
相关产品推荐
相关产品推荐

