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
相关产品推荐
相关产品推荐

