Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法使用毒丸阻止生产者/消费者线程_Java_Multithreading_Thread Safety_Interrupt - Fatal编程技术网

Java 无法使用毒丸阻止生产者/消费者线程

Java 无法使用毒丸阻止生产者/消费者线程,java,multithreading,thread-safety,interrupt,Java,Multithreading,Thread Safety,Interrupt,我有一个非常简单的代码,它模拟了使用毒丸的生产者/消费者停止技术 我有制片人班: public class Producer extends Thread { private final BlockingQueue<String> queue; public Producer(BlockingQueue<String> queue) { this.queue = queue; } @Override publi

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

我有制片人班:

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.println1;将导致程序在生产者线程中断后退出


请帮助我了解原因。

我的猜测是,您的生产商比您的消费者运行得快得多,您似乎永远不会用完商品。在没有显式容量的情况下创建LinkedBlockingQueue会创建一个具有capacity Integer.MAX_值的队列,这足以让使用者保持打印一段时间

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


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

我的猜测是,你的制作人比你的消费者运行得快得多,你似乎永远不会用完物品。在没有显式容量的情况下创建LinkedBlockingQueue会创建一个具有capacity Integer.MAX_值的队列,这足以让使用者保持打印一段时间

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


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

您也可以在发布避孕药之前清空队列。您也可以在发布避孕药之前清空队列。