当前位置: 首页 > 知识库问答 >
问题:

为什么ArrayBlockingQueue在队列已满时没有被阻塞

史淇
2023-03-14

我对ArrayBlockingQueue进行了一个简单的测试,如下所示:

public class TestQueue {

    static class Producer implements Runnable {
        private ArrayBlockingQueue<Integer> queue;
        private int index;

        public Producer(ArrayBlockingQueue<Integer> queue, int index) {
            this.queue = queue;
            this.index = index;
        }

        @Override
        public void run() {
            try {
                queue.put(index);

                System.out.println("producer: " + index);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class Consumer implements Runnable {
        private ArrayBlockingQueue<Integer> queue;

        public Consumer(ArrayBlockingQueue<Integer> queue) {
            this.queue = queue;
        }

        @Override
        public void run() {
            try {
                while(true) {
                    System.out.println("consumer: " + queue.take());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);

        for (int i = 0; i < 10; i++) {
            Producer producer = new Producer(queue, i);

            new Thread(producer).start();
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Consumer consumer = new Consumer(queue);

        new Thread(consumer).start();
    }
}

结果是:

producer: 2
producer: 0
producer: 1
consumer: 0
producer: 4
producer: 6
consumer: 2
etc...

我的问题是,我已经将ArrayBlockingQueue的大小定义为3,而制作人将2、0和1放入队列,总共3个项目,现在队列已满,然后消费者消费了0,队列大小现在应为2,然后制作人将4放入队列,现在队列应已满,为什么制作人仍可以将6放入队列,应该被阻止

共有2个答案

狄晟睿
2023-03-14

事实上,生产者:6在消费者:2之前打印到您的控制台,并不意味着在删除消费者:2之前添加了生产者:6。

如果您在添加和删除项目之前和之后打印队列的大小,您会看到它永远不会超过3。

劳亦
2023-03-14

取/放动作和打印不是原子的。

生产者:6印在消费者:2之前,并不意味着生产者将6印在消费者消费2之前。

例如:

  1. 使用者执行队列。take(),和take 2
 类似资料:
  • 这是为编写的: 有界队列。当与有限的maximumPoolSizes一起使用时,有界队列(例如ArrayBlockingQueue)有助于防止资源耗尽,但可能更难调优和控制。队列大小和最大池大小可以相互权衡:使用大队列和小池可以最大限度地减少CPU使用量、OS资源和上下文切换开销,但可能会导致人为的低吞吐量。如果任务经常阻塞(例如,如果它们是I/O绑定的),系统可能能够为更多的线程安排时间,而不是

  • 本文向大家介绍Java源码解析阻塞队列ArrayBlockingQueue介绍,包括了Java源码解析阻塞队列ArrayBlockingQueue介绍的使用技巧和注意事项,需要的朋友参考一下 Java的阻塞队列,在实现时,使用到了lock和condition,下面是对其主要方法的介绍。 首先看一下,阻塞队列中使用到的锁。 主要的锁是一个可重入锁,根据注释,它是用来保证所有访问的同步。此外,还有2个

  • 这是我第一次问有关StackOverflow的问题。我的问题如下: 我有一个生产者和消费者类。在Producer类中,我逐行读取文件,并将这些文本行放入字符串列表中。当列表的行数为x时。此列表将添加到ArrayBlockingQueue。我有一个在主线程中启动的生产者线程。除此之外,我还启动了几个消费者线程。使用者线程从队列中获取一个项目,该项目应该是一个列表,并遍历该行列表以查找特定单词。找到单

  • 本文向大家介绍Java源码解析阻塞队列ArrayBlockingQueue功能简介,包括了Java源码解析阻塞队列ArrayBlockingQueue功能简介的使用技巧和注意事项,需要的朋友参考一下 本文基于jdk1.8进行分析。 阻塞队列是java开发时常用的一个数据结构。首先看一下阻塞队列的作用是什么。阻塞队列的作用,从源码中类的注释中来了解,是最清晰准确的。 ArrayBlockingQue

  • 问题内容: 该蟒蛇线程 文档指出“......线程仍然是一个合适的模型,如果你想同时运行多个I / O密集型任务”,这显然是因为I / O密集型进程能够避免GIL是在并行执行的线程阻止受CPU限制的任务。 但是我不明白的是,一个I / O任务仍然使用CPU。那么它怎么可能不会遇到相同的问题呢?是否因为I / O绑定任务不需要内存管理? 问题答案: 将在CPython的GIL 1中 只 涉及执行Py

  • Envelope.java 主ube.java Cube.java(直到这里它的工作) 货币ube.java