Java中同一对象的同步getValue与setValue方法如何同时执行?
核心问题解析:wait()/notify()与synchronized的协作逻辑
你疑问的核心是没搞懂wait()方法的关键特性:当线程在synchronized方法/块里调用wait()时,它会主动释放持有的对象锁,然后进入该对象的等待队列,直到被notify()/notifyAll()唤醒。这也是这段代码里的getValue()和setValue()能协作工作,而非一个线程占着锁不让另一个执行的原因。
代码执行流程拆解
1. 初始状态:available = false
- 若生产者线程先调用setValue():
因为available为false,跳过while循环,设置value后将available改为true,调用notifyAll()唤醒所有等待该对象锁的线程,方法执行完毕后释放锁。 - 若消费者线程先调用getValue():
因为available为false,进入while循环并调用wait(),此时线程释放Data对象的锁,进入等待状态。
2. 生产者执行完setValue后,消费者被唤醒
消费者线程被notifyAll()唤醒后,会重新尝试获取Data对象的锁(此时生产者已释放锁,能成功获取)。再次检查available为true,退出while循环,将available改为false,调用notifyAll()唤醒可能等待的生产者线程,返回value后释放锁。
3. 消费者执行完getValue后,生产者被唤醒
若此时有生产者线程因available为true进入wait()状态,被notifyAll()唤醒后会重新获取锁,检查available为false后,即可执行setValue的写入逻辑。
为什么wait()/notify()不是毫无意义?
这段代码是典型生产者-消费者模型的基础实现:
- 它保证生产者仅在无可用数据(available=false)时写入,消费者仅在有可用数据(available=true)时读取,避免数据混乱。
- 如果没有wait()/notify(),你只能让线程不断循环检查available状态(忙等待),会持续浪费CPU资源;而wait()让线程在条件不满足时进入休眠,直到条件满足被唤醒,大幅节省系统资源。
关于“同时执行”的误区
getValue()和setValue()不会同时执行——因为它们都是synchronized方法,同一时间只能有一个线程持有Data对象的锁。但wait()的存在让线程不会一直占用锁,而是在条件不满足时主动释放,让其他线程有机会执行,从而实现有序的协作,而非无限等待。
内容的提问来源于stack exchange,提问作者Hasan Rüzgar
相关产品推荐
相关产品推荐

