Table of Contents
ToggleLinkedBlockingQueue in Java with Examples
是執行緒安全的無界佇列,表示在建立時若未指定佇列的大小,其佇列可以隨著元素的增加而動態增長,但是,如果沒有足夠的記憶體,則會拋出 OutOfMemoryError ,如果有給定大小,那就是固定容量的佇列, Java LinkedBlockingQueue Examples 介紹常見的 forEach 、 iterator 、 spliterator 、 trySplit 、 drainTo 等方法,本篇增加了範例,並透過單元測試來驗證產出結果。
檔案目錄
./
+- src
+- test
| +- org
| +- ruoxue
| +- java_147
| +- queue
| +- linkedblockingqueue
| +- LinkedBlockingQueueMethodsTest.java
單元測試
Java BlockingQueue 提供循環訪問、佇列匯出、轉成陣列等操作列表中的元素。
forEach
建立一個 LinkedBlockingQueue ,內有三個元素,迴圈取得元素。
@Test
public void forEach() {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
queue.forEach(e -> System.out.println(e));
}
Papaya
Strawberry
Watermelon
forEachRemaining
建立一個 LinkedBlockingQueue ,內有三個元素,迴圈取得剩餘元素。
@Test
public void forEachRemaining() {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
Iterator<String> it = queue.iterator();
int i = 0;
while (it.hasNext()) {
System.out.println(it.next());
if (i == 1) {
break;
}
i++;
}
System.out.println("----------");
it.forEachRemaining(e -> {
System.out.println(e);
});
}
Papaya
Strawberry
----------
Watermelon
iterator
Java BlockingQueue 建立一個 LinkedBlockingQueue ,內有三個元素,迴圈取得元素。
@Test
public void iterator() {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
Iterator<String> it = queue.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
Papaya
Strawberry
Watermelon
spliterator
Java BlockingQueue 建立一個 LinkedBlockingQueue ,內有三個元素,使用 spliterator 取得元素,等同於 iterator.hasNext 和 iterator.next。
@Test
public void spliterator() {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
Spliterator<String> sit = queue.spliterator();
sit.tryAdvance(e -> System.out.println(e));
System.out.println("----------");
sit.forEachRemaining(e -> System.out.println(e));
System.out.println("----------");
sit = queue.spliterator();
while (sit.tryAdvance(e -> System.out.println(e))) {
}
}
Papaya
----------
Strawberry
Watermelon
----------
Papaya
Strawberry
Watermelon
trySplit
Java BlockingQueue 建立一個 LinkedBlockingQueue ,內有三個元素,使用 spliterator 取得元素,trySplit 將目前的拆分器分為兩個新的拆分器並行處理。
@Test
public void trySplit() {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
Spliterator<String> sit = queue.spliterator();
Spliterator<String> sit2 = sit.trySplit();
System.out.println(sit.getExactSizeIfKnown());
sit.forEachRemaining(e -> System.out.println(e));
System.out.println("----------");
System.out.println(sit2.getExactSizeIfKnown());
sit2.forEachRemaining(e -> System.out.println(e));
}
-1
Strawberry
Watermelon
----------
1
Papaya
toArray
Java LinkedBlockingQueue 建立一個 LinkedBlockingQueue ,內有三個元素, 轉換成 String 陣列。
@Test
public void toArray() {
int expectedSize = 3;
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
String[] array = new String[queue.size()];
queue.toArray(array);
for (String e : array) {
System.out.println(e);
}
assertEquals(expectedSize, array.length);
}
Papaya
Strawberry
Watermelon
streamToArray
Java LinkedBlockingQueue 建立一個 LinkedBlockingQueue ,內有三個元素,使用 Stream ,轉換成 String 陣列。
@Test
public void streamToArray() {
int expectedSize = 3;
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
String[] array = queue.stream().toArray(String[]::new);
for (String e : array) {
System.out.println(e);
}
assertEquals(expectedSize, array.length);
}
Papaya
Strawberry
Watermelon
drainTo
建立一個 LinkedBlockingQueue ,內有三個元素,元素全部匯出到另一個佇列。
@Test
public void drainTo() {
int expectedSize = 0;
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
System.out.println(queue);
BlockingQueue<String> queue2 = new LinkedBlockingQueue<String>();
queue.drainTo(queue2);
System.out.println(queue);
System.out.println(queue2);
assertEquals(expectedSize, queue.size());
assertEquals(3, queue2.size());
}
[Papaya, Strawberry, Watermelon]
[]
[Papaya, Strawberry, Watermelon]
drainToMaxElements
建立一個 LinkedBlockingQueue ,內有三個元素,匯出指定數量元素到另一個佇列。
@Test
public void drainToMaxElements() {
int expectedSize = 2;
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
System.out.println(queue);
BlockingQueue<String> queue2 = new LinkedBlockingQueue<String>();
queue.drainTo(queue2, 1);
System.out.println(queue);
System.out.println(queue2);
assertEquals(expectedSize, queue.size());
assertEquals(1, queue2.size());
}
[Papaya, Strawberry, Watermelon]
[Strawberry, Watermelon]
[Papaya]
LinkedBlockingQueueWithExamplesTest.java
Java LinkedBlockingQueue 新增單元測試,驗證是否符合預期。
package org.ruoxue.java_147.queue.linkedblockingqueue;
import static org.junit.Assert.*;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import org.junit.Test;
public class LinkedBlockingQueueWithExamplesTest {
@Test
public void forEach() {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
queue.forEach(e -> System.out.println(e));
}
@Test
public void forEachRemaining() {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
Iterator<String> it = queue.iterator();
int i = 0;
while (it.hasNext()) {
System.out.println(it.next());
if (i == 1) {
break;
}
i++;
}
System.out.println("----------");
it.forEachRemaining(e -> {
System.out.println(e);
});
}
@Test
public void iterator() {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
Iterator<String> it = queue.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
@Test
public void spliterator() {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
Spliterator<String> sit = queue.spliterator();
sit.tryAdvance(e -> System.out.println(e));
System.out.println("----------");
sit.forEachRemaining(e -> System.out.println(e));
System.out.println("----------");
sit = queue.spliterator();
while (sit.tryAdvance(e -> System.out.println(e))) {
}
}
@Test
public void trySplit() {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
Spliterator<String> sit = queue.spliterator();
Spliterator<String> sit2 = sit.trySplit();
System.out.println(sit.getExactSizeIfKnown());
sit.forEachRemaining(e -> System.out.println(e));
System.out.println("----------");
System.out.println(sit2.getExactSizeIfKnown());
sit2.forEachRemaining(e -> System.out.println(e));
}
@Test
public void toArray() {
int expectedSize = 3;
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
String[] array = new String[queue.size()];
queue.toArray(array);
for (String e : array) {
System.out.println(e);
}
assertEquals(expectedSize, array.length);
}
@Test
public void streamToArray() {
int expectedSize = 3;
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
String[] array = queue.stream().toArray(String[]::new);
for (String e : array) {
System.out.println(e);
}
assertEquals(expectedSize, array.length);
}
@Test
public void drainTo() {
int expectedSize = 0;
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
System.out.println(queue);
BlockingQueue<String> queue2 = new LinkedBlockingQueue<String>();
queue.drainTo(queue2);
System.out.println(queue);
System.out.println(queue2);
assertEquals(expectedSize, queue.size());
assertEquals(3, queue2.size());
}
@Test
public void drainToMaxElements() {
int expectedSize = 2;
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.add("Papaya");
queue.add("Strawberry");
queue.add("Watermelon");
System.out.println(queue);
BlockingQueue<String> queue2 = new LinkedBlockingQueue<String>();
queue.drainTo(queue2, 1);
System.out.println(queue);
System.out.println(queue2);
assertEquals(expectedSize, queue.size());
assertEquals(1, queue2.size());
}
}
心得分享
Java BlockingQueue Examples 執行緒安全是通過悲觀鎖來保證的,使用兩個獨立的 ReentrantLocks 進行寫和讀操作,這可以防止生產者和消費者執行緒之間的訪問衝突, ArrayBlockingQueue 僅受一個 ReentrantLock 保護,因此生產者線程和消費者執行緒之間的訪問衝突是有可能的, Java LinkedBlockingQueue 提供了幾種 LinkedBlockingQueue 常見方法的操作範例。