You need to enable JavaScript to run this app. Java线程间通信:生产者消费者POC一轮后双线程永久等待问题求助
优惠活动
大模型
产品
解决方案
定价
更多

Java线程间通信:生产者消费者POC一轮后双线程永久等待问题求助

核心问题定位
  • 递归执行链路断裂:原代码依赖递归调用实现连续生产/消费的逻辑,仅在未达到边界值时走else分支递归。一旦触发边界条件(box=0 或 box=10)进入wait分支,wait返回后没有后续逻辑重新触发方法调用,synchronized方法直接执行完毕,对应线程随即终止。
    按原代码执行流举例:消费者线程将box从5减到0后进入wait状态,等生产者notify唤醒时,会从递归栈顶逐层返回,整个方法链执行结束,线程生命周期终止,没有任何后续消费动作。
  • 唤醒逻辑闭环缺失:当生产者生产到box=10的上限时,调用notify唤醒处于wait状态的消费者,但消费者被唤醒后直接终止线程,没有反向调用notify叫醒仍处于wait状态的生产者,最终生产者永久阻塞在wait,整个程序停止。
  • 线程等待逻辑不规范:原代码使用if判断等待条件,没有遵循Java wait机制的使用规范——wait被唤醒后需要重新校验条件,这种写法既可能触发虚假唤醒导致的逻辑错误,也进一步加剧了执行链路的断裂。
  • notify()唤醒时机错位:notify()仅能随机唤醒一个处于wait队列的线程,原代码中消费者在box减到0时调用notify,此时生产者还在阻塞等待对象锁、并未进入wait队列,这次唤醒完全无效,没有起到任何通知作用。
可实现持续循环的优化方案

修正核心思路:

  • 用无限循环替代递归逻辑,维持生产/消费动作的持续执行入口,从根源上避免递归链断裂的问题
  • 将所有等待判断的if改为while,wait被唤醒后重新校验边界条件,符合Java线程模型的安全要求
  • 将边界位置的notify()替换为notifyAll(),确保所有等待线程都能被唤醒,避免随机唤醒导致的永久阻塞
  • 生产/消费动作执行完成后主动唤醒等待线程,形成双向通知的逻辑闭环,避免出现双方都卡在wait的死锁状态

修正后的完整代码:

public class ProducerConsumerWithThreads {

    synchronized void withdrawBoxConsumer() {
        while (true) {
            // 库存为0时消费者进入等待
            while (box == 0) {
                System.out.println("Please put more boxes");
                notifyAll();
                try {
                    wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    System.out.println("Consumer thread interrupted, exiting");
                    return;
                }
            }
            box--;
            System.out.println("Took one box now boxes left " + box);
            // 消费完成后主动唤醒所有等待线程
            notifyAll();
        }
    }

    synchronized void putBoxProducer() {
        while (true) {
            // 库存达到上限时生产者进入等待
            while (box == 10) {
                System.out.println("Please Consume boxes");
                notifyAll();
                try {
                    wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    System.out.println("Producer thread interrupted, exiting");
                    return;
                }
            }
            box++;
            System.out.println("Put one box now boxes are " + box);
            // 生产完成后主动唤醒所有等待线程
            notifyAll();
        }
    }

    public int box = 5;

    public static void main(String[] args) throws InterruptedException {
        final ProducerConsumerWithThreads c = new ProducerConsumerWithThreads();

        new Thread(c::withdrawBoxConsumer, "consumer-thread").start();
        new Thread(c::putBoxProducer, "producer-thread").start();
    }
}

修正后的执行效果:程序会持续在库存为0时触发消费者等待、生产者连续生产,库存到上限时触发生产者等待、消费者连续消费,形成无间断的循环执行逻辑,不会出现两个线程永久阻塞的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 22:36:01