Java 单生产者多消费者-队列包含null

Java 单生产者多消费者-队列包含null,java,multithreading,queue,Java,Multithreading,Queue,有人能解释一下下面的consumer-2是如何使用“null”的吗?我的代码应该阻止这种情况 public class Test { public static void main(String args[]) throws InterruptedException { BoundedQueue<Integer> sharedQueue = new BoundedQueue<>(10); Callable<Integer> produce

有人能解释一下下面的consumer-2是如何使用“null”的吗?我的代码应该阻止这种情况

public class Test {

public static void main(String args[]) throws InterruptedException {

    BoundedQueue<Integer> sharedQueue = new BoundedQueue<>(10);

    Callable<Integer> producer1 = new Producer(sharedQueue, "producer-1");
    //Callable<Integer> producer2 = new Producer(sharedQueue, "producer-2");
    Callable<Integer> consumer1 = new Consumer(sharedQueue, "consumer-1");
    Callable<Integer> consumer2 = new Consumer(sharedQueue, "consumer-2");

    Collection<Callable<Integer>> callables = new HashSet<>();
    callables.add(producer1);
    //callables.add(producer2);
    callables.add(consumer1);
    callables.add(consumer2);

    ExecutorService executorService = Executors.newFixedThreadPool(10);
    executorService.invokeAll(callables);
}
}

public class BoundedQueue<T> {

private int capacity;
private int head;
private int tail;
private int currentSizeOfBuffer;
private T[] buffer;

private final ReentrantLock lock = new ReentrantLock();
private final Condition notFull = lock.newCondition();
private final Condition notEmpty = lock.newCondition();

public BoundedQueue(int capacity) {
    this.capacity = capacity;
    this.buffer = (T[]) new Object[capacity];
}

public void put(T element) throws InterruptedException {

    final ReentrantLock lock = this.lock;
    lock.lock();

    if(isBufferFull()) {
        waitOnAvailableSlot();
    }

    try {
        buffer[tail] = element;
        tail = getNextAvailableSlot(tail);
        currentSizeOfBuffer++;

        informConsumerQueueHasElement();

    } finally {
        lock.unlock();
    }
}

private boolean isBufferFull() {
    return capacity == currentSizeOfBuffer;
}

private void waitOnAvailableSlot() throws InterruptedException {
    notFull.await();
}

private void informConsumerQueueHasElement() {
    notEmpty.signal();
}

public T take() throws InterruptedException {

    final ReentrantLock lock = this.lock;
    lock.lock();

    if(isBufferEmpty()) {
        waitOnAvailableElement();
    }

    try {
        T element = buffer[head];
        head = getNextAvailableSlot(head);
        currentSizeOfBuffer--;

        informProducerQueueHasSpaceAvailable();

        return element;
    } finally {
        lock.unlock();
    }
}

private boolean isBufferEmpty() {
    return 0 == currentSizeOfBuffer;
}

private void waitOnAvailableElement() throws InterruptedException {
    notEmpty.await();
}

private void informProducerQueueHasSpaceAvailable() {
    notFull.signal();
}

private final int getNextAvailableSlot(int currentSlotPosition) {
    int nextAvailableSlot = ++currentSlotPosition;
    return (nextAvailableSlot == capacity) ? 0 : nextAvailableSlot;
}
}


public class Producer implements Callable<Integer> {

private final BoundedQueue sharedQueue;
private String name;

@Override
public Integer call() throws Exception {

    for(int i=0; i<10; i++){
        try {
            sharedQueue.put(i);
            System.out.println(name + " produced: " + i);
        } catch (InterruptedException ex) {
            Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    return null;
}

public Producer(BoundedQueue sharedQueue, String name) {
    this.sharedQueue = sharedQueue;
    this.name = name;
}
}

public class Consumer implements Callable<Integer> {

private final BoundedQueue sharedQueue;
private String name;

@Override
public Integer call() throws Exception {

    while(true){    //what is happening here?
        try {
            Integer element = (Integer) sharedQueue.take();
            System.out.println(name + " consumed: "+ element);
        } catch (InterruptedException ex) {
            Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

public Consumer(BoundedQueue sharedQueue, String name) {
    this.sharedQueue = sharedQueue;
    this.name = name;
}
}
公共类测试{
公共静态void main(字符串args[])引发InterruptedException{
BoundedQueue sharedQueue=新的BoundedQueue(10);
Callable producer1=新生产者(sharedQueue,“生产者-1”);
//Callable producer2=新生产者(sharedQueue,“生产者-2”);
Callable consumer1=新消费者(sharedQueue,“消费者-1”);
Callable consumer2=新消费者(sharedQueue,“消费者-2”);
Collection callables=new HashSet();
callables.add(producer1);
//callables.add(producer2);
callables.add(consumer1);
callables.add(consumer2);
ExecutorService ExecutorService=Executors.newFixedThreadPool(10);
executorService.invokeAll(可调用项);
}
}
公共类有界队列{
私人int能力;
私人内部主管;
私人内特尾;
私有int currentSizeOfBuffer;
专用T[]缓冲区;
private final ReentrantLock lock=new ReentrantLock();
private final Condition notFull=lock.newCondition();
private final Condition notEmpty=lock.newCondition();
公共边界队列(整数容量){
这个。容量=容量;
this.buffer=(T[])新对象[容量];
}
公共void put(T元素)抛出InterruptedException{
最终重入锁定=this.lock;
lock.lock();
if(isBufferFull()){
waitOnAvailableSlot();
}
试一试{
缓冲区[尾]=元素;
tail=getNextAvailableSlot(tail);
currentSizeOfBuffer++;
informConsumerQueueHasElement();
}最后{
lock.unlock();
}
}
私有布尔值isBufferFull(){
返回容量==currentSizeOfBuffer;
}
私有void waitOnAvailableSlot()引发InterruptedException{
未满。等待();
}
私有void informConsumerQueueHasElement(){
notEmpty.signal();
}
public T take()抛出InterruptedException{
最终重入锁定=this.lock;
lock.lock();
if(isBufferEmpty()){
waitOnAvailableElement();
}
试一试{
T元素=缓冲器[头部];
head=getNextAvailableSlot(head);
currentSizeOfBuffer--;
informProducerQueueHasSpaceAvailable();
返回元素;
}最后{
lock.unlock();
}
}
私有布尔值isBufferEmpty(){
返回0==currentSizeOfBuffer;
}
私有void waitOnAvailableElement()引发InterruptedException{
notEmpty.wait();
}
私有void informProducerQueueHasSpaceAvailable(){
notFull.signal();
}
专用最终int getNextAvailableSlot(int currentSlotPosition){
int nextAvailableSlot=++currentSlotPosition;
返回(nextAvailableSlot==容量)?0:nextAvailableSlot;
}
}
公共类生产者实现了可调用{
私有最终边界队列sharedQueue;
私有字符串名称;
@凌驾
公共整数调用()引发异常{

对于(int i=0;i您需要使用
while(isBufferEmpty())
,而不仅仅是
if
(对于full也一样)。由于所有消费者(和生产者)都会同时收到信号,因此您必须重新检查以确保其他消费者尚未处理添加到队列中的元素