繁体   English   中英

将add()和take()元素添加到BlockingQueue时发生死锁

[英]Deadlock while add() and take() elements to BlockingQueue

我正在使用java.util.concurrent包,并使用其接口/类来了解它们的工作方式。 我创建了一个BlockingQueue实例( ArrayBlockingQueue imlpementation)。 并创建了50个Rannable类型的消费者和50个生产者。 然后使用Executors.newFixedThreadPool(4)创建一个大小为4的线程池,并将我的所有消费者/生产者提交到threadPool (ExecutorService)。 但是最终我发现该过程是deadlock 谁能解释为什么线程安全队列陷入僵局!? 下面是我的代码:

消费者:

public class ArrayBlockingQueueConsumer implements Runnable{

    BlockingQueue<Integer> blockingQueue;
    int consumerNumber = 0;

    public ArrayBlockingQueueConsumer(BlockingQueue<Integer> blockingQueue, int consumerNumber) {
        this.blockingQueue = blockingQueue;
        this.consumerNumber = consumerNumber;
    }

    public void run() {
        int i = 0;
        while(i<60) {
            System.out.printf("Consumer %d going take %d from blocking queue\n", consumerNumber, i);
            try {
                int x = blockingQueue.take();
                System.out.println("The number " + x + "is taken from the queue.");
            } catch (InterruptedException e) {
                System.out.printf("Consumer %d interrupted while adding %d to blocking queue\n", consumerNumber, i);
                e.printStackTrace();
            }
            i++;
        }
    }
}

制片人:

public class ArrayBlockingQueueProducer implements Runnable{

    BlockingQueue<Integer> blockingQueue;
    int producerNumber = 0;

    public ArrayBlockingQueueProducer(BlockingQueue<Integer> blockingQueue, int producerNumber) {
        this.blockingQueue = blockingQueue;
        this.producerNumber = producerNumber;
    }

    public void run() {
        int i = 0;
        while(i<60) {
            System.out.printf("Consumer %d going to add %d to blocking queue\n", producerNumber, i);
            blockingQueue.add(i);
            System.out.printf("Consumer %d added %d to blocking queue\n", producerNumber, i);
            i++;
        }
    }

}

执行程序类(main()方法类):

public class BlockingQueueExecutor {

    public static void main(String[] args) {
        BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(50);

        ArrayBlockingQueueConsumer[] consumers = new ArrayBlockingQueueConsumer[200];
        ArrayBlockingQueueProducer[] producers = new ArrayBlockingQueueProducer[200];

        System.out.println("Hello hello :D");

        for (int i = 0; i < 200; i++) {
            consumers[i] = new ArrayBlockingQueueConsumer(blockingQueue, i+1);
            producers[i] = new ArrayBlockingQueueProducer(blockingQueue, i+1);
        }

        ExecutorService threadPool = Executors.newFixedThreadPool(4);

        for (int i = 0; i < 200; i++) {
            threadPool.execute(consumers[i]);
            threadPool.execute(producers[i]);
        }

        threadPool.shutdown();
    }
}

我在使用者/生产者中的循环从0到60运行,以便他们在找不到任何元素或找不到队列已满时可以抛出异常,具有讽刺意味的是,生产者/消费者没有一个抛出任何异常。

我在使用者/生产者中的循环从0到60运行,以便他们在找不到任何元素或找不到队列已满时可以抛出异常,具有讽刺意味的是,生产者/消费者没有一个抛出任何异常。

当队列为空时, take()不会引发异常。 等待直到元素可用。

E java.util.concurrent.BlockingQueue.take()抛出InterruptedException

检索并删除此队列的头部, 如有必要 ,请等待直到元素变为可用为止

这里没有僵局。 您的代码在BlockingQueue.add()调用中为我抛出了IllegalStateException 这导致队列未达到计划的满载状态,最终导致take() 阻塞 ,如记录所示。 不死锁。

死锁是指两个或多个线程因为彼此都在等待而无法继续进行的情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM