代码之家  ›  专栏  ›  技术社区  ›  gesanri

为什么队列已满时未阻止ArrayBlockingQueue

  •  2
  • gesanri  · 技术社区  · 6 年前

    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 回复  |  直到 6 年前
        1
  •  1
  •   xingbin    6 年前

    执行/执行操作和打印不是原子的。

    producer: 6 以前打印过 consumer: 2 ,并不意味着生产者把6放在消费者消费2之前。

    例如:

    1. 生产者执行队列.put(6)
    2. 生产者印刷品 制作人:6人
    3. 消费品脱 消费者:2
        2
  •  0
  •   Eran    6 年前

    事实上 producer: 6 打印到您的控制台之前 consumer: 2 6 在之前添加 2 被移除。

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