ArrayBlockingQueue 與 LinkedBlockingQueue
一、概述
Java BlockingQueue
接口代表一個線程安全的隊列。如果隊列已滿,它會阻止試圖將元素放入隊列的線程。如果隊列為空,它還會阻止試圖從隊列中獲取元素的線程。
BlockingQueue 有多種實現,如ArrayBlockingQueue
、 LinkedBlockingQueue
、 SynchronousQueue
、 PriorityBlockingQueue
。
在本教程中,我們將了解ArrayBlockingQueue
和LinkedBlockingQueue
之間的區別。
2. ArrayBlockingQueue
ArrayBlockingqueue
是一個有界隊列。它在內部使用一個數組。我們可以在創建實例時提及數組的大小。
下面的代碼片段顯示了我們如何創建ArrayBlockingQueue
的對象。我們提到內部數組的大小為10
:
int INIT_CAPACITY = 10;
BlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(INIT_CAPACITY, true);
如果我們在隊列中插入超出定義容量的元素並且隊列已滿,則添加操作會拋出IllegalStateException
。此外,如果我們將初始大小設置為小於1
,我們將得到IllegalArgumentException
。
這裡第二個參數表示公平策略。我們可以選擇設置公平策略來保持阻塞的生產者和消費者線程的順序。它允許以 FIFO 順序對阻塞線程進行隊列訪問。因此,先進入等待狀態的線程將首先獲得訪問隊列的機會。這有助於避免線程飢餓。
3. LinkedBlockingQueue
LinkedBlockingQueue
是BlockingQueue
的可選有界實現。它由鏈接節點支持。
我們還可以在創建實例時指定容量。如果未指定,則Integer.MAX_VALUE
設置為容量。
插入元素時動態創建鏈接節點。
讓我們看看如何創建LinkedBlockingQueue
:
BlockingQueue<String> linkedBlockingQueue = new LinkedBlockingQueue<>();
4. ArrayBlockingQueue
與LinkedBlockingQueue
儘管ArrayBlockingQueue
和LinkedBlockingQueue
都是BlockingQueue
的實現,並且以 FIFO 順序存儲元素,但它們之間還是存在一定的差異。現在我們來看看這些差異:
特徵 | ArrayBlockingQueue | LinkedBlockingQueue |
執行 | 它由一個數組支持 | 它使用鏈接節點 |
隊列大小 | 這是一個有界隊列。因此,在創建時必須指定初始容量。 | 不必提及尺寸。 |
公平政策 | 我們可以在裡面設置一個公平策略 | 沒有選項可以在此設置公平策略 |
鎖數 | 它使用一個ReentrantLock 。 put 和 take 操作使用同一個鎖。 | 它使用單獨的ReentrantLock 進行讀寫操作。這可以防止生產者和消費者線程之間的爭用。 |
內存空間 | 由於必須在其中提及初始容量,因此我們最終可以分配比所需更多的空間。 | 它通常不預先分配節點。因此,它的內存佔用與其大小相匹配 |
5.結論
在本文中,我們了解了ArrayBlockingQueue
和LinkedBlockingQueue
之間的區別。 ArrayBlockingQueue
由數組備份, LinkedBlockingQueue
由鏈接節點備份。我們還談到了ArrayBlockingQueue
中存在的公平策略的附加功能以及兩個隊列的鎖定機制和內存佔用。
與往常一樣,示例的源代碼可在 GitHub 上獲得。