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

Java中调用wait()是否释放所有锁?多线程锁释放场景实测疑问

问题原因说明

1. 测试代码存在设计错误,和wait()机制无关

你代码中定义的LOCK_OBJECT是TestSync类的实例成员变量,没有加static修饰,这意味着每创建一个TestSync实例,都会生成一个全新的LOCK_OBJECT对象。而你在业务逻辑中分别给生产者、消费者创建了两个完全独立的TestSync实例:

  • 生产者线程持有的是第一个new TestSync()实例的LOCK_OBJECT锁
  • 消费者线程竞争的是第二个new TestSync()实例的LOCK_OBJECT锁
    两把锁本质是不同的对象,不存在任何竞争关系,因此消费者可以直接拿到锁,不需要等生产者释放,这就是你看到的测试结果的核心原因。

2. 你对wait()方法的锁释放规则确实存在误解

Java中Object.wait()的核心规则是:调用哪个对象的wait()方法,就只会释放该对象的监视器锁,线程当前持有的其他所有锁都不会被主动释放。
你可以修改代码验证这个规则:将LOCK_OBJECT、FULL、amount都改为static修饰的类成员,让两个线程共享同一把LOCK_OBJECT锁,重新运行后你会发现消费者会一直阻塞,无法打印Consumer get LOCK_OBJECT lock日志,因为生产者调用FULL.wait()时只会释放FULL的锁,不会释放持有的LOCK_OBJECT锁,符合预期的锁规则。

修正代码参考
public class TestSync {
    // 改为static类级别成员,所有实例共享
    private static volatile Integer amount = 0;
    private static final Object LOCK_OBJECT = new Object();
    private static final Object FULL = new Object();

    public void doubleSync() throws InterruptedException {
        System.out.println("Producer  trying to get LOCK_OBJECT lock ");
        synchronized (LOCK_OBJECT) {
            System.out.println("Producer get LOCK_OBJECT lock ");
            Print.sleep(3000);
            while (amount >= 0) {
                synchronized (FULL) {
                    System.out.println("full!");
                    FULL.wait();
                }
            }
            System.out.println("continue~");
            amount++;
        }
    }

    public void simpleSync() {
        System.out.println("Consumer trying to get LOCK_OBJECT lock ");
        synchronized (LOCK_OBJECT) {
            System.out.println("Consumer get LOCK_OBJECT lock");
        }
        System.out.println("Consumer release LOCK_OBJECT lock");
    }

    // main方法逻辑保持原有实现即可
}

内容的提问来源于stack exchange,提问作者kebukeyi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:06:08