2

可能重复:
我在 Consumer 内收到 NullPointerException

这是否被认为是 Producer , Consumer Scenario 中的错误?

这是我的 Producer 类。

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 字母的情况。

这个输出有问题吗??正如我看到的语句 Producer0produced 同时两次,然后是 Consumer0consumed 语句同时针对字母 e 和 f 。

我担心使用此代码我会错过 Producer 生成的任何信息吗?

请指教 ??

感谢您的建议。

4

3 回答 3

2

这个输出有问题吗?

没有。在消费者设法消费第一个项目之前,您的生产者线程刚刚设法生产了第二个项目。这是完全自然的,尤其是当你随机睡觉时。

当然,您可能希望为队列指定一个上限 - 然后使用offer而不是add检测队列已满的情况 - 但您显示的输出很好。

于 2012-09-20T13:50:13.400 回答
0

正如我看到的语句 Producer0produced 同时两次,然后是 Consumer0consumed 语句同时针对字母 e 和 f 。

不,这是意料之中的。您正在演示多线程的典型异步行为。生产者能够在消费者睡觉时生成 2 个字母。

这将发生,特别是考虑到生产者和消费者都在进行随机睡眠:

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

但即使没有睡眠,线程程序也会出现这种不对称行为。

于 2012-09-20T13:50:26.300 回答
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 回答