You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 09:15:23