2

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

我有生产者类:

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");会导致程序在生产者线程中断后退出。

请帮助我理解为什么。

4

1 回答 1

4

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

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

尝试创建一个LinkedBlockingQueue小容量的,比如 100 左右,而不是。

于 2013-03-18T23:57:17.400 回答