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

AtomicBoolean未更新问题:基于BlockingQueue的生产者消费者程序排查

完善你的生产者-消费者模型:消费者实现方案

结合你描述的需求(生产者生产200个正整数产品后,放入-1作为停止信号),我帮你补全并优化消费者的实现代码,确保能正确识别停止信号并优雅终止:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

public class Consumer implements Runnable {
    private BlockingQueue<Integer> queue;
    private AtomicBoolean isProducerClosed = new AtomicBoolean(false);

    public Consumer(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            while (!isProducerClosed.get()) {
                Integer product = queue.take();
                // 识别停止信号
                if (product == -1) {
                    isProducerClosed.set(true);
                    // 多消费者场景注意:把-1放回队列,让其他消费者也能收到停止信号
                    // queue.put(-1);
                    System.out.println("消费者收到停止信号,准备终止");
                    break;
                }
                // 处理正常产品的逻辑
                processProduct(product);
            }
        } catch (InterruptedException e) {
            // 响应中断,保留中断状态以支持上层优雅退出
            Thread.currentThread().interrupt();
            System.out.println("消费者线程被中断,终止运行");
        }
    }

    // 模拟产品处理逻辑,可替换为实际业务代码
    private void processProduct(Integer product) {
        System.out.println("消费者处理产品:" + product);
    }
}

关键细节拆解

  • 停止信号处理:当取出的元素是-1时,立刻将isProducerClosed置为true并终止循环。如果是多消费者场景,一定要把-1重新放回队列,避免其他消费者永远阻塞在take()方法上。
  • 线程安全的状态标记:用AtomicBoolean来标记生产者是否停止,保证多线程环境下状态的可见性和原子性,不会出现线程安全问题。
  • 中断异常处理:BlockingQueue.take()会抛出InterruptedException,捕获后要重新设置线程的中断状态,这样上层逻辑能感知到中断,实现真正的优雅退出。
  • 循环终止条件:结合isProducerClosed状态控制循环,既响应停止信号,也能处理线程被中断的异常情况。

配套生产者实现(供参考)

import java.util.concurrent.BlockingQueue;

public class Producer implements Runnable {
    private BlockingQueue<Integer> queue;
    private static final int PRODUCE_COUNT = 200;

    public Producer(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            for (int i = 1; i <= PRODUCE_COUNT; i++) {
                queue.put(i);
                System.out.println("生产者生产产品:" + i);
                // 模拟生产耗时,可根据实际情况调整
                Thread.sleep(10);
            }
            // 生产完成,放入停止信号
            queue.put(-1);
            System.out.println("生产者完成生产,发出停止信号");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.out.println("生产者线程被中断,终止生产");
        }
    }
}

这套逻辑能完美匹配你的需求:生产者生产200个产品后发出停止信号,消费者捕获信号后停止工作,同时兼顾了单/多消费者场景的兼容性~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:05:20