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

Java生产者消费者程序无法终止异常排查及模型应用场景咨询

Java生产者消费者代码异常修复及相关问题解答

代码无法运行的核心问题

你的代码存在三处逻辑错误,直接导致程序卡死无法终止:

  • Model类的writeData方法逻辑位置错误:写数据、修改状态、唤醒线程的代码放在了while(!isEmpty)代码块内部,首次调用写方法时isEmpty为true,不会进入while块,写操作完全没有执行,读线程永远等不到数据陷入永久等待
  • ModelThreadReader的循环逻辑错误:循环迭代部分仅调用readData()但没有将返回值赋值给msg变量,导致msg永远是第一次读取的结果,永远匹配不到终止条件done
  • 字符串比较使用==而非equals:Java中比较字符串内容必须使用equals()方法,==比较的是对象内存地址,虽然本例中常量字符串碰巧生效,但属于错误写法

修正后的完整代码

public class Test {
    public static void main(String[] args) {
        Model model = new Model();
        new Thread(new ModelThreadWriter(model)).start();
        new Thread(new ModelThreadReader(model)).start();
    }
}

class Model {
    private String data;
    private boolean isEmpty = true;

    public synchronized void writeData(String data) {
        while (!isEmpty) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 写逻辑移到while循环外部
        this.data = data;
        isEmpty = false;
        notifyAll();
    }

    public synchronized String readData() {
        while (isEmpty) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        isEmpty = true;
        notifyAll();
        return data;
    }
}

class ModelThreadWriter implements Runnable {
    private Model model;

    public ModelThreadWriter(Model model) {
        this.model = model;
    }
    
    @Override
    public void run() {
        String[] text = {
            "Text 1",
            "Text 2",
            "Text 3"
        };

        for (int i=0; i<text.length; i++) {
            model.writeData(text[i]);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        model.writeData("done");
    }
}

class ModelThreadReader implements Runnable {
    private Model model;

    public ModelThreadReader(Model model) {
        this.model = model;
    }

    @Override
    public void run() {
        String msg;
        // 修改循环逻辑,每次读取的内容赋值给msg,用equals比较字符串
        while (!(msg = model.readData()).equals("done")) {
            System.out.println(msg);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

相关问题解答

生产者消费者模型的适用场景

  • 削峰填谷:上游生产速度波动大时,通过缓冲区暂存数据,下游按稳定速度消费,避免服务被突发流量打垮
  • 模块解耦:生产者和消费者仅依赖公共缓冲区,不需要感知对方的实现逻辑,任意一方的迭代修改都不会直接影响另一方
  • 异步处理:将不需要立即返回结果的任务交给下游异步执行,提升上游系统的响应速度
  • 批量操作:消费端积攒一定量数据后做批量处理(比如批量写数据库、批量上报日志),减少IO次数,提升系统性能

Java入门开发者是否值得学习该模型

非常值得。生产者消费者是并发编程领域最经典的入门模型:

  • 可以帮你快速掌握Java基础并发工具的使用,包括synchronized同步锁、wait/notify线程通信机制,理解线程安全、竞态条件的核心概念
  • 该模型是很多高级中间件的底层实现逻辑,比如线程池、消息队列等,搞懂这个模型后你后续学习这些高级组件会事半功倍
  • 掌握这个模型后你能解决很多实际开发中的简单并发问题,对你提升Java开发能力帮助很大

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:45:02