在本教程中,我們將借助示例來學(xué)習(xí)LinkedBLockingQueue類及其方法。
Java Collections框架的LinkedBlockingQueue類使用鏈表提供阻塞隊列實現(xiàn)。
它實現(xiàn)了Java BlockingQueue接口。
為了創(chuàng)建鏈表阻塞隊列,我們必須導(dǎo)入java.util.concurrent.LinkedBlockingQueue包。
這是我們?nèi)绾卧贘ava中創(chuàng)建鏈表阻塞隊列的方法:
1.無初始容量
LinkedBlockingQueue<Type> animal = new LinkedBlockingQueue<>();
在此,默認(rèn)初始容量為2 31 -1。
2.具有初始容量
LinkedBlockingQueue<Type> animal = new LinkedBlockingQueue<>(int capacity);
這里,
Type - 鏈表阻塞隊列的類型
capacity - 鏈表阻塞隊列的大小
例如,
//創(chuàng)建大小為5的字符串類型LinkedBlockingQueue LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5); //創(chuàng)建大小為5的整數(shù)類型LinkedBlockingQueue LinkedBlockingQueue<Integer> age = new LinkedBlockingQueue<>(5);
注意:并不是必須提供鏈表的大小。
LinkedBlockingQueue類提供了的BlockingQueue的接口所有方法的實現(xiàn)。
這些方法用于從鏈接的阻塞隊列中插入,訪問和刪除元素。
此外,我們還將學(xué)習(xí)兩種方法put(),take(),它們支持鏈表阻塞隊列中的阻塞操作。
這兩種方法將鏈表阻塞隊列與其他典型隊列區(qū)分開來。
add() - 將指定的元素插入到鏈表阻塞隊列中。如果隊列已滿,它將拋出異常。
offer() - 將指定的元素插入到鏈表阻塞隊列中。如果隊列已滿,則返回false。
例如,
import java.util.concurrent.LinkedBlockingQueue; class Main { public static void main(String[] args) { LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5); // 使用 add() animals.add("Dog"); animals.add("Cat"); // 使用 offer() animals.offer("Horse"); System.out.println("LinkedBlockingQueue: " + animals); } }
輸出結(jié)果
LinkedBlockingQueue: [Dog, Cat, Horse]
peek() - 從鏈表阻塞隊列的前面返回一個元素。如果隊列為空,則返回null。
iterator() - 返回一個迭代器對象,以按順序訪問鏈表阻塞隊列中的元素。如果隊列為空,則拋出異常。我們必須導(dǎo)入java.util.Iterator軟件包才能使用它。
例如,
import java.util.concurrent.LinkedBlockingQueue; import java.util.Iterator; class Main { public static void main(String[] args) { LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5); //添加元素 animals.add("Dog"); animals.add("Cat"); animals.add("Horse"); System.out.println("LinkedBlockingQueue: " + animals); // 使用 peek() String element = animals.peek(); System.out.println("訪問元素: " + element); // 使用 iterator() Iterator<String> iterate = animals.iterator(); System.out.print("LinkedBlockingQueue 元素: "); while(iterate.hasNext()) { System.out.print(iterate.next()); System.out.print(", "); } } }
輸出結(jié)果
LinkedBlockingQueue: [Dog, Cat, Horse] 訪問元素: Dog LinkedBlockingQueue 元素: Dog, Cat, Horse,
remove() - 返回并從鏈表阻塞隊列中刪除指定的元素。如果隊列為空,則拋出異常。
poll() - 返回并從鏈表阻塞隊列中刪除指定的元素。如果隊列為空,則返回null。
clear() - 從鏈表阻塞隊列中刪除所有元素。
例如,
import java.util.concurrent.LinkedBlockingQueue; class Main { public static void main(String[] args) { LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5); animals.add("Dog"); animals.add("Cat"); animals.add("Horse"); System.out.println("LinkedBlockingQueue " + animals); // 使用 remove() String element1 = animals.remove(); System.out.println("刪除元素:"); System.out.println("使用 remove(): " + element1); // 使用 poll() String element2 = animals.poll(); System.out.println("使用 poll(): " + element2); // 使用 clear() animals.clear(); System.out.println("更新后的LinkedBlockingQueue " + animals); } }
輸出結(jié)果
LinkedBlockingQueue: [Dog, Cat, Horse] 刪除元素: 使用 remove(): Dog 使用 poll(): Cat 更新后的LinkedBlockingQueue: []
在多線程過程中,我們可以使用put()和take()阻塞一個線程的操作以使其與另一個線程同步。這些方法將等待,直到可以成功執(zhí)行。
要將指定的元素插入到鏈表阻塞隊列的末尾,我們使用put()方法。
如果鏈表阻塞隊列已滿,它將等待,直到鏈表阻塞隊列中有足夠的空間來插入元素。
例如,
import java.util.concurrent.LinkedBlockingQueue; class Main { public static void main(String[] args) { LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5); try { //添加元素到animals animals.put("Dog"); animals.put("Cat"); System.out.println("LinkedBlockingQueue: " + animals); } catch(Exception e) { System.out.println(e); } } }
輸出結(jié)果
LinkedBlockingQueue: [Dog, Cat]
在此,如果在等待時被中斷,put()方法可能會拋出一個InterruptedException。因此,我們必須將其包含在try..catch塊中。
要從鏈表阻塞隊列的前面返回并刪除一個元素,我們可以使用take()方法。
如果鏈表阻塞隊列為空,它將等待,直到鏈表阻塞隊列中有要刪除的元素為止。
例如,
import java.util.concurrent.LinkedBlockingQueue; class Main { public static void main(String[] args) { LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5); try { //添加元素到 animals animals.put("Dog"); animals.put("Cat"); System.out.println("LinkedBlockingQueue: " + animals); //刪除一個元素 String element = animals.take(); System.out.println("刪除元素: " + element); System.out.println("新的LinkedBlockingQueue: " + animals); } catch(Exception e) { System.out.println(e); } } }
輸出結(jié)果
LinkedBlockingQueue: [Dog, Cat] 刪除元素: Dog 新的LinkedBlockingQueue: [Cat]
在此,如果在等待時被中斷,該take()方法將拋出InterrupedException。因此,我們必須將其封閉在一個try...catch塊內(nèi)。
方法 | 內(nèi)容描述 |
---|---|
contains(element) | 在鏈表阻塞隊列中搜索指定的元素。如果找到該元素,則返回true,否則返回false。 |
size() | 返回鏈表阻塞隊列的長度。 |
toArray() | 將鏈表阻塞隊列轉(zhuǎn)換為數(shù)組并返回該數(shù)組。 |
toString() | 將鏈表阻塞隊列轉(zhuǎn)換為字符串 |
LinkedBlockingQueue使用鏈表作為其內(nèi)部存儲。
它被認(rèn)為是線程安全的集合。因此,它通常用于多線程應(yīng)用程序中。
假設(shè)一個線程正在將元素插入隊列,而另一個線程正在從隊列中刪除元素。
現(xiàn)在,如果第一個線程比第二個線程慢,則鏈表阻塞隊列可使第二個線程等待,直到第一個線程完成其操作。