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

Java生产者消费者程序输出超大数值异常原因咨询

生产者消费者模式超大数值输出问题解答

问题原因说明

不是CPU速度过快导致的问题,核心原因是你的生产者线程使用了无限循环且未设置终止条件:

  • 生产者的run()方法里是while(true),会持续执行queue.put(i++),变量i会不断自增,随着程序运行时间增加,i的数值会变得越来越大,直到int类型溢出(此时数值会变为负数)。
  • 书本示例输出Put:1/Got:1到Put:5/Got:5,是因为书本代码的生产者是有限循环(比如只循环5次),而你误写成了无限循环。

你的代码同步逻辑是正确的,所以每次Put和对应的Got数值都是一致的,只是无限循环导致数值不断累积变大。

你的完整代码

Main类

public class Main {
    public static void main(String[] args) {
        Q queue = new Q();

        Producer producer = new Producer(queue);
        Consumer consumer = new Consumer(queue);

        producer.thread.start();
        consumer.thread.start();
    }
}

Q类(同步队列)

public class Q {
    int n;
    boolean ready = false;

    synchronized int get(){
        while (!ready){
            try {
                wait();
            } catch (InterruptedException e){
                System.out.println("Consumer thread was interrupted!");
                System.out.println();
                System.out.println(e);
            }
        }

        System.out.println("Got: " + n);
        ready = false;
        notify();
        return n;
    }

    synchronized void put(int n){
        while (ready){
            try {
                wait();
            } catch (InterruptedException e){
                System.out.println("Consumer thread was interrupted!");
                System.out.println();
                System.out.println(e);
            }
        }

        this.n = n;
        ready = true;
        System.out.println("Put: " +  n);
        notify();
    }
}

Producer类(生产者)

public class Producer implements Runnable{
    Q queue;
    Thread thread;

    Producer(Q queue){
        thread = new Thread(this, "Producer");
        this.queue = queue;
    }

    @Override
    public void run() {
        int i = 0;

        while (true){
            queue.put(i++);
        }
    }
}

Consumer类(消费者)

public class Consumer implements Runnable{
    Q queue;
    Thread thread;

    Consumer(Q queue){
        thread = new Thread(this, "Consumer");
        this.queue = queue;
    }

    @Override
    public void run() {
        while (true){
            queue.get();
        }
    }
}

修正方案

如果你想得到书本的示例输出,只需要把生产者的无限循环改成有限循环即可,比如循环5次:

@Override
public void run() {
    for(int i = 0; i < 5; i++){
        queue.put(i+1); // 从1开始输出,和书本示例一致
    }
}

同时可以给消费者线程添加终止逻辑,避免线程一直运行:

@Override
public void run() {
    for(int i = 0; i < 5; i++){
        queue.get();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 05:45:44