說起JAVA中的阻塞隊列,就不得不提到JAVA中的集合,隊列Queue繼承了Collection的所有的方法,也是一種集合的表現形式。
下圖是java中collection相關的一些接口,主要列出了有關阻塞隊列的相關類和接口。
上圖總結了常見的集合接口和類的繼承和實現關係,用於更清晰把握他們之間的關係和內部實現方式,主要針對於Queue。
下面大致總結一下圖中主要類的方法和關係。
Collection && AbstractCollection
1、Collection是接口,包含了操作集合的最基本的方法。AbstractCollection是實現了Collection接口的抽象類,圖中ArrayQueue和ConcurrentLinkedDeque就是繼承自AbstractCollection抽象類。
2、Collection接口中的方法有:
boolean add(E) , boolean remove(E) ,size(),iterator(),contains(),toArray()等集合最基本的操作方法。
Queue && AbstractQueue
1、Queue是隊列集合的接口,繼承自Collection接口,除此之外,Queue接口中還增加了一些額外的接口:
- boolean offer(E e); 向隊列中添加元素。當隊列已滿時,則返回false。而add方法當隊列已滿時會拋出異常,add的內部實現調用的是offer方法。
- E poll(); 刪除隊列中的第一個元素,當隊列爲空時返回null,而remove方法則會拋出異常,remove的內部實現調用的是poll方法。
- E element(); 獲取隊列頭部的第一個元素但不刪除,當隊列爲空時會拋出異常,element的內部實現調用的是peek方法。
- E peek(); 獲取隊列頭部的第一個元素但不刪除,當隊列爲空時返回null。
2、AbstractQueue是實現了Queue接口的抽象類。
BlockingQueue
1、BlockingQueue接口是有關阻塞隊列的相關接口,它繼承自Queue接口。除了Queue中提供有關隊列相關的方法外,還額外提供了有關阻塞隊列相關的操作方法。
- void put(E e) throws InterruptedException; 向隊列中添加一個元素,當隊列滿時,阻塞,等待隊列可用時添加。
- E take() throws InterruptedException; 從隊列中取出一個元素,當隊列爲空時,阻塞,直到隊列中有元素時取出。
2、BlockingQueue對應的隊列爲單向隊列,通常指FIFO。
3、BlockingQueue相關的方法都是線程安全的。
小結
下圖總結了有關BlockingQueue相關的方法
Deque
1、Deque雙端隊列接口,繼承自Queue接口。既然是雙端隊列,那麼隊列的頭尾都可以進行進出,所以它還擁有棧的能力。因此,Deque中同時聲明瞭雙端隊列和棧的實現方法。
其中隊列的方法包括(只雙端隊列):
- void addFirst(E e); 向隊列頭部添加一個元素。當隊列滿時,則拋出異常。
- void addLast(E e); 向隊列尾部添加一個元素,當隊列滿時,拋出異常。
- boolean offerFirst(E e); 向隊列頭部添加一個元素,當隊列滿時,返回false。
- boolean offerLast(E e); 向隊列尾部添加一個元素,當隊列滿時,返回false。
- E removeFirst(); 移除隊列頭部的一個元素,當隊列爲空時,拋出異常。
- E removeLast(); 移除隊列尾部一個元素,當隊列爲空時,拋出異常。
- E pollFirst(); 移除隊列頭部一個元素,當隊列爲空時,返回null。
- E pollLast(); 移除隊列尾部一個元素,當隊列爲空時,返回null。
- E getFirst();E getLast();E peekFirst();E peekLast();
棧的操作方法包括:
- void push(E e); 向棧頂壓入一個元素,當棧空間滿時,拋出異常。
- E pop(); 從棧頂彈出一個元素,當棧爲空時,則拋出異常。
2、特殊說明一下,LinkedList類同時實現了Deque和List接口。
BlockingDeque
1、BlockingDeque接口繼承了Deque接口和BlockingQueue接口。同時擁有了隊列和雙端隊列以及阻塞隊列的方法。相比與Deque和BlockingQueue,增加了以下方法:
- void putFirst(E e) throws InterruptedException; 向隊列頭部添加一個元素,如果隊列滿,則阻塞,直到隊列可用爲止。
- void putLast(E e) throws InterruptedException; 向隊列尾部添加一個元素,如果隊列滿,則阻塞,直到隊列可用爲止。
- E takeFirst() throws InterruptedException; 從隊列頭部取出一個元素,當隊列爲空時阻塞,直到隊列中有元素取出成功爲止。
- E takeLast() throws InterruptedException; 從隊列尾部取出一個元素,當隊列爲空時阻塞,直到隊列中有元素取出成功爲止。
2、BlockingDeque也是線程安全的雙端隊列。
小結
下圖總結了有關BlockingDeque相關的方法
ConcurrentLinkedQueue && ConcurrentLinkedDeque
1、故名思議,這兩個爲線程安全的Queue和Deque。在Queue接口下,BlockingQueue和ConcurrentLinkedQueue是兩個線程安全的單向隊列,其中BlockingQueue是通過鎖實現線程安全的,而concurrentLinkedQueue則是通過CAS來實現線程安全的。
而BlockingDeque和ConcurrentLinkedDeque則是線程安全的雙端隊列。
2、二者不同的是,ConcurrentLinkedQueue是繼承了AbstractQueue接口實現了Queue接口。
而ConcurrentLinkedDeque則是直接實現了Deque的接口,繼承了AbstractCollection類。
其實本質都是共用了並且重寫了一部分AbstractCollection類中的方法。
以上是對java隊列中的各個接口和類的一個總結,接下來的博客會繼續總結關於阻塞隊列的相關知識。