2

重複の可能性:
コンシューマー内でNullPointerExceptionが発生しています

これは、プロデューサー、コンシューマーシナリオのバグと見なされますか?

これは私のプロデューサークラスです。

package com ;

import java.util.concurrent.PriorityBlockingQueue;

public class Producer extends CommonClass implements Runnable {
    private SyncronizedStack stack;
    private int producerNum;

    Producer(PriorityBlockingQueue<Character> queue) {
        this.queue = queue;
    }

    public void run() {

        char ch;

        for (ch = 'a'; ch <= 'f'; ch++) {
            queue.add(ch);
            System.out.println("Producer" + producerNum + "produced :" + ch);
            try {
                Thread.sleep((int) (Math.random() * 300));

            } catch (InterruptedException e) {
                System.out.println("Error");
            }

        }

    }

}

これは私の消費者クラスです

package com ;

import java.util.concurrent.PriorityBlockingQueue;

public class Consumer extends CommonClass implements Runnable {

    private int consumerNum;

    Consumer(PriorityBlockingQueue<Character> queue) {
        this.queue = queue;
    }

    public void run() {
        char c;
        for (int i = 0; i < 7; i++) {
            try {
                c = queue.take();
                System.out.println("Consumer" + consumerNum + "consumed:" + c);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            try {
                Thread.sleep((int) (Math.random() * 300));
            } catch (InterruptedException e) {
                System.out.println("Error");
            }
        }

    }
}

これは私のCommonClassです

package com ;

import java.util.concurrent.PriorityBlockingQueue;

public class CommonClass {

    PriorityBlockingQueue<Character> queue = null;

}

これは私のクライアントプログラムです

package com ;

import java.util.concurrent.PriorityBlockingQueue;

public class SyncTest {

    public static void main(String[] args) {

        CommonClass cs = new CommonClass();

        PriorityBlockingQueue<Character> queue = new PriorityBlockingQueue<Character>();

        Producer p1 = new Producer(queue);
        Thread t1 = new Thread(p1);
        t1.start();

        Consumer c1 = new Consumer(queue);
        Thread ct1 = new Thread(c1);

        ct1.start();

    }
}

これを実行すると、次のように出力されます

Producer0produced :a
Consumer0consumed:a

Producer0produced :b
Consumer0consumed:b

Producer0produced :c
Consumer0consumed:c

Producer0produced :d
Consumer0consumed:d

Producer0produced :e
Producer0produced :f
Consumer0consumed:e
Consumer0consumed:f

これは、eおよびfアルファベットの場合です。

この出力に問題はありますか?私が見るように、ステートメントProducer0が同時に2回生成され、その後に文字eとfのConsumer0consumedステートメントが同時に続きます。

このコードでは、プロデューサーが作成した情報を見逃してしまうのではないかと心配しています。

ご意見をお聞かせください ??

アドバイスありがとうございます。

4

3 に答える 3

2

この出力に問題はありますか?

いいえ。コンシューマーが最初のアイテムを消費する前に、プロデューサースレッドが2番目のアイテムを生成することができました。これは、特にランダムな期間眠っている場合は、まったく自然なことです。

もちろん、キューに上限を設定し、キューがいっぱいになった状況を検出するoffer代わりに使用することもできますが、表示した出力は問題ありません。add

于 2012-09-20T13:50:13.400 に答える
0

これはバグですか?

回答-いいえこれは、不必要な睡眠を追加しているために発生します。

Thread.sleep((int) (Math.random() * 300));

以下にあるプロデューサーコンシューマーのバージョンを簡略化しました。

public class Example {

public static class Producer implements Runnable {
    private PriorityBlockingQueue<Character> queue;

    Producer(PriorityBlockingQueue<Character> queue) {
        this.queue = queue;
    }

    public void run() {
        char ch;
        for (ch = 'a'; ch <= 'f'; ch++) {
            queue.put(ch);
        }
    }
}

public static class Consumer implements Runnable {

    private PriorityBlockingQueue<Character> queue;

    Consumer(PriorityBlockingQueue<Character> queue) {
        this.queue = queue;
    }

    public void run() {
        for (int i = 0; i < 7; i++) {
            try {
                System.out.println("Consumer take :" + queue.take());
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();// Propagate interrupt
            }
        }
    }
}

public static void main(String[] args) {
    ExecutorService executorService = Executors.newFixedThreadPool(2);
    PriorityBlockingQueue<Character> queue = new PriorityBlockingQueue<Character>(7);
    executorService.execute(new Producer(queue));
    executorService.execute(new Consumer(queue));
    executorService.shutdown();
}

}
于 2012-09-20T14:25:22.787 に答える
0

私が見るように、ステートメントProducer0が同時に2回生成され、その後に文字eとfのConsumer0consumedステートメントが同時に続きます。

いいえ、それは予想されることです。複数のスレッドの典型的な非同期動作を示しています。消費者が寝ている間に、プロデューサーは2文字を作成することができました。

これは、特にプロデューサーとコンシューマーの両方がランダムなスリープを実行していることを考慮すると発生します。

Thread.sleep((int) (Math.random() * 300));

ただし、スリープがない場合でも、スレッド化されたプログラムではこのような非対称の動作が予想されます。

于 2012-09-20T13:50:26.300 に答える