簡體   English   中英

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

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

我已經聲明了一個大小為 1 的 BlockingQueue

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

但我可以在隊列中添加超過 1 個元素。 我確信我在這方面遺漏了一些東西,這是 BlockingQueue 的核心屬性。 這是 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);
    }

但是當我實現時,我能夠產生超過 1 個元素,根據我的說法,如果 BlockingQueue 的大小為 1,那么在產生 1 個元素之后,它應該等待消費者使用該元素。 這是代碼和代碼的output。

我需要一個解釋,請你幫我解決這個問題。

我試過谷歌搜索和 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

將打印更改為

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

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

你會看到它們實際上沒有按正確的時間順序打印

這只是兩個線程之間的競爭條件。

您相信它產生了第二條消息,因為您在消費者之前看到了生產者的 output 很幸運,他的System.out在消費者的處理之前得到了處理。

嘗試調試它,你會看到沒有添加第二個元素,而消費者之前沒有閱讀第一個元素。 不要相信控制台輸出中的順序......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM