【问题标题】:Can't stop producer/consumer threads with Poison Pill无法使用 Poison Pill 停止生产者/消费者线程
【发布时间】:2013-03-18 23:47:18
【问题描述】:

我有非常简单的代码,它使用“毒丸”模拟生产者/消费者停止技术。

我有 Producer 类:

public class Producer extends Thread {

    private final BlockingQueue<String> queue;

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

    @Override
    public void run() {
        try {
        while (true) {
                //unblocking this line will cause the code to stop after intrrupt               
                //System.out.println("1");
                queue.put("hello world");
            }
        } catch (InterruptedException e) {
                try {
                    queue.put(Main.POISON_PILL);
                } catch (InterruptedException e1) {
                }
            }
        }
}

消费类:

public class Consumer extends Thread {

    private final BlockingQueue<String> queue;

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

    @Override
    public void run() {
        try {
            while (true) {
                String s = queue.take();
                if (s.equals(Main.POISON_PILL))
                    break;
                else
                    System.out.println(s);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

现在主要功能:

public static String POISON_PILL = "POISON_PILL";

    public static void main(String[] args) {

        BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
        Producer producer = new Producer(queue);
        Consumer consumer = new Consumer(queue);
        producer.start();
        consumer.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {

        } finally {
            producer.interrupt();
        }
    }

由于未知原因,即使在producer.interrupt() 调用之后, “hello world”永远在控制台中打印。

我不明白的第二件事是为什么取消注释System.out.println("1"); 会导致程序在生产者线程中断后退出。

请帮助我理解原因。

【问题讨论】:

    标签: java multithreading thread-safety interrupt


    【解决方案1】:

    我的猜测是,您的生产者运行速度比您的消费者快得多,以至于您似乎永远不会用完项目。创建一个没有显式容量的LinkedBlockingQueue 会创建一个容量为 Integer.MAX_VALUE 的LinkedBlockingQueue,这足以让消费者继续打印一段时间。

    这也可能是添加System.out.println 行时它开始工作的原因;通过要求控制台 I/O,它会减慢生产者的速度,直到消费者能够跟上。

    尝试创建一个容量较小的LinkedBlockingQueue,例如 100 左右。

    【讨论】:

    • 您也可以在发布药丸之前排空队列。
    猜你喜欢
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 2017-02-01
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    相关资源
    最近更新 更多