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()ですが、「helloworld」はコンソールで永遠に印刷を続けます。

私が理解できない2番目のことは、コメントを解除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 に答える