简体   繁体   English

阻塞队列在 java 中不起作用,我可以放置比阻塞队列定义大小更多的元素

[英]Blocking queue not working in java, I can put more element than the defined size of blocking queue

I have declared a BlockingQueue of size 1我已经声明了一个大小为 1 的 BlockingQueue

final BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(1); . .

But I am able to add more than 1 element into the queue.但我可以在队列中添加超过 1 个元素。 I am sure I am missing something in this like this is the core property of BlockingQueue.我确信我在这方面遗漏了一些东西,这是 BlockingQueue 的核心属性。 Here is the code from java docs.这是 java 文档中的代码。

    /**
     * Creates an {@code ArrayBlockingQueue} with the given (fixed)
     * capacity and default access policy.
     *
     * @param capacity the capacity of this queue
     * @throws IllegalArgumentException if {@code capacity < 1}
     */
    public ArrayBlockingQueue(int capacity) {
        this(capacity, false);
    }

But when I am implementing I am able to produce more than 1 element, according to me if the size of the BlockingQueue is 1 then after producing 1 element it should wait for the consumer to consume the element.但是当我实现时,我能够产生超过 1 个元素,根据我的说法,如果 BlockingQueue 的大小为 1,那么在产生 1 个元素之后,它应该等待消费者使用该元素。 Here is the code and the output of the code.这是代码和代码的output。

I need an explanation for this, can you please help me with this.我需要一个解释,请你帮我解决这个问题。

I have tried google search and StackOverflow with no success.我试过谷歌搜索和 StackOverflow 都没有成功。

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class BlockingQueueTestWorking {

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

        Runnable producer = () -> {
            try {
                int iterator = 0;
                while (true) {
                    if (iterator++ == 10)
                        break;

                    String name = Thread.currentThread().getName();
                    Integer i = (int) (Math.random() * 10);
                    blockingQueue.put(i);
                    System.out.println(name + " Producing:-> " + i);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        Runnable consumer = () -> {
            try {
                int iterator = 0;
                while (true) {
                    if (iterator++ == 10)
                        break;
                    String name = Thread.currentThread().getName();
                    Integer take = blockingQueue.take();
                    System.out.println(name + " Consuming:<- " + take);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        Thread threadProducer = new Thread(producer);


        final ExecutorService executor = Executors.newFixedThreadPool(10);
        executor.execute(threadProducer);
        
        Thread threadConsumer = new Thread(consumer);
        executor.execute(threadConsumer);

        executor.shutdown();
    }

}

Output:
pool-1-thread-1 Producing:-> 2
pool-1-thread-1 Producing:-> 7
pool-1-thread-2 Consuming:<- 2
pool-1-thread-2 Consuming:<- 7
pool-1-thread-1 Producing:-> 6
pool-1-thread-2 Consuming:<- 6
pool-1-thread-1 Producing:-> 2
pool-1-thread-2 Consuming:<- 2
pool-1-thread-1 Producing:-> 6
pool-1-thread-2 Consuming:<- 6
pool-1-thread-1 Producing:-> 1
pool-1-thread-2 Consuming:<- 1
pool-1-thread-1 Producing:-> 2
pool-1-thread-2 Consuming:<- 2
pool-1-thread-1 Producing:-> 2
pool-1-thread-2 Consuming:<- 2
pool-1-thread-1 Producing:-> 2
pool-1-thread-2 Consuming:<- 2
pool-1-thread-1 Producing:-> 4
pool-1-thread-2 Consuming:<- 4

Change the print to将打印更改为

System.out.println(String.format("[%s]", new Timestamp(System.currentTimeMillis())) + " Producing:-> " + i);

and

System.out.println(String.format("[%s]", new Timestamp(System.currentTimeMillis())) + name + " Consuming:<- " + take);

and you will see that they are actually not printed in the correct time order你会看到它们实际上没有按正确的时间顺序打印

This is just a race condition between both threads.这只是两个线程之间的竞争条件。

You believe it produced a second message because you see the output of the producer before of the consumer one .您相信它产生了第二条消息,因为您在消费者之前看到了生产者的 output It was lucky and his System.out was processed before the consumer's one.很幸运,他的System.out在消费者的处理之前得到了处理。

Try debugging it, and you'll see no second element is being added without the consumer reading the first one before.尝试调试它,你会看到没有添加第二个元素,而消费者之前没有阅读第一个元素。 Don't believe the order in console outputs ...不要相信控制台输出中的顺序......

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

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