簡介
Queue、Deque 前面已經分析過,它們不是線程安全的,如果非要在多線程中使用Queue或Deque,那么只能把整個隊列對象鎖住,操作完成在釋放鎖,這樣非常消耗性能,就算多個線程操作不同的元素也要鎖整個隊列想想都恐怖,有沒有更好的辦法?JDK中提供了阻塞隊列BlockingQueue、BlockingDeque專門用來解決多線程使用隊列問題。
BlockingQueue 接口
public interface BlockingQueue<E> extends Queue<E>
BlockingQueue 繼承Queue
BlockingQueue 方法
// 添加,滿時拋異常
boolean add(E e);
// 添加,滿時返回false
boolean offer(E e);
// 添加,滿時阻塞
void put(E e) throws InterruptedException;
// 添加,滿時阻塞,超時返回false
boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;
// 出隊,空時阻塞
E take() throws InterruptedException;
// 出隊,空時阻塞,超時返回null
E poll(long timeout, TimeUnit unit) throws InterruptedException;
// 剩余容量(理想情況下)
int remainingCapacity();
// 刪除元素,失敗返回false(這里和remove()不一樣)
boolean remove(Object o);
// 是否包含
public boolean contains(Object o);
// 從該隊列中移除所有可用元素,並將它們添加到給定集合中
int drainTo(Collection<? super E> c);
// 從該隊列中移除最多給定數量的可用元素,並將它們添加到給定集合中。
int drainTo(Collection<? super E> c, int maxElements);
BlockingDeque 接口
public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E>
BlockingDeque 繼承BlockingQueue 和 Deque 兩個接口
BlockingDeque 方法
// 頭部添加
void addFirst(E e);
// 尾部添加
void addLast(E e);
// 頭部添加
boolean offerFirst(E e);
// 尾部添加
boolean offerLast(E e);
// 頭部添加,滿時阻塞
void putFirst(E e) throws InterruptedException;
// 尾部添加,滿時阻塞
void putLast(E e) throws InterruptedException;
// 頭部添加,滿時阻塞,超時返回false
boolean offerFirst(E e, long timeout, TimeUnit unit)
throws InterruptedException;
// 尾部添加,滿時阻塞,超時返回false
boolean offerLast(E e, long timeout, TimeUnit unit)
throws InterruptedException;
// 頭部出隊,空時阻塞
E takeFirst() throws InterruptedException;
// 尾部出隊,空時阻塞
E takeLast() throws InterruptedException;
// 頭部出隊,空時阻塞,超時返回null
E pollFirst(long timeout, TimeUnit unit)
throws InterruptedException;
// 尾部出隊,空時阻塞,超時返回null
E pollLast(long timeout, TimeUnit unit)
throws InterruptedException;
// 從頭部刪除元素
boolean removeFirstOccurrence(Object o);
// 從尾部刪除元素
boolean removeLastOccurrence(Object o);
// 添加,滿時拋異常
boolean add(E e);
// 添加,滿時返回false
boolean offer(E e);
// 添加,滿時阻塞
void put(E e) throws InterruptedException;
// 添加,滿時阻塞,超時返回false
boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException;
// 出隊,空時拋異常
E remove();
// 出隊,空時返回null
E poll();
// 出隊,空時阻塞
E take() throws InterruptedException;
// 出隊,空時阻塞,超時返回null
E poll(long timeout, TimeUnit unit)
throws InterruptedException;
// 查詢,空時異常
E element();
// 查詢,空時返回null
E peek();
// 刪除元素,空時返回false
boolean remove(Object o);
// 是否包含
public boolean contains(Object o);
// 長度
public int size();
// 迭代器
Iterator<E> iterator();
// 添加,滿時拋異常
void push(E e);
阻塞隊列擴展非阻塞隊列,提供阻塞,阻塞超時等方法。當隊列中為空時,從隊列中獲取元素的操作將被阻塞,當隊列滿時,向隊列中添加元素的操作將被阻塞。試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其它的線程往隊列中插入新的元素。同樣,試圖往滿的隊列中添加新元素的線程也會被阻塞,直到有其他的線程使隊列重新變的空閑起來。
拋出異常:當隊列滿時,再向隊列中插入元素,則會拋出IllegalStateException異常。當隊列空時,再向隊列中獲取元素,則會拋出NoSuchElementException異常。
返回特殊值:當隊列滿時,向隊列中添加元素,則返回false,否則返回true。當隊列為空時,向隊列中獲取元素,則返回null,否則返回元素。
一直阻塞:當阻塞隊列滿時,如果生產者向隊列中插入元素,則隊列會一直阻塞當前線程,直到隊列可用或響應中斷退出。當阻塞隊列為空時,如果消費者線程向阻塞隊列中獲取數據,則隊列會一直阻塞當前線程,直到隊列空閑或響應中斷退出。
超時退出:當隊列滿時,如果生產線程向隊列中添加元素,則隊列會阻塞生產線程一段時間,超過指定的時間則退出返回false。當隊列為空時,消費線程從隊列中移除元素,則隊列會阻塞一段時間,如果超過指定時間退出返回null。