原創轉載請注明出處:https://www.cnblogs.com/agilestyle/p/11394436.html
線程安全隊列類圖
兩者的區別在於
- ConcurrentLinkedQueue基於CAS的無鎖技術,不需要在每個操作時使用鎖,所以擴展性表現要更加優異,在常見的多線程訪問場景,一般可以提供較高吞吐量。
- LinkedBlockingQueue內部則是基於鎖,並提供了BlockingQueue的等待性方法。
BlockingQueue基本都是基於鎖實現,比如典型的LinkedBlockingQueue
有界隊列
- ArrayBlockingQueue是最典型的的有界隊列,其內部以final的數組保存數據,數組的大小就決定了隊列的邊界,所以我們在創建ArrayBlockingQueue時,都要指定容量,如
public ArrayBlockingQueue(int capacity, boolean fair)
- LinkedBlockingQueue,容易被誤解為無邊界,但其實其行為和內部代碼都是基於有界的邏輯實現的,只不過如果我們沒有在創建隊列時就指定容量,那么其容量限制就自動被設置為Integer.MAX_VALUE,成為了無界隊列。
- SynchronousQueue,這是一個非常奇葩的隊列實現,每個刪除操作都要等待插入操作,反之每個插入操作也都要等待刪除動作。那么這個隊列的容量是多少呢?是1嗎?其實不是的,其內部容量是0。
無界隊列
- PriorityBlockingQueue是無邊界的優先隊列,雖然嚴格意義上來講,其大小總歸是要受系統資源影響。
- DelayedQueue和LinkedTransferQueue同樣是無邊界的隊列。對於無邊界的隊列,有一個自然的結果,就是put操作永遠也不會發生其他BlockingQueue的那種等待情況。
有界隊列使用場景
以LinkedBlockingQueue、ArrayBlockingQueue和SynchronousQueue為例,根據需求可以從很多方面考量:
- 考慮應用場景中對隊列邊界的要求。ArrayBlockingQueue是有明確的容量限制的,而LinkedBlockingQueue則取決於我們是否在創建時指定,SynchronousQueue則干脆不能緩存任何元素。
- 從空間利用角度,數組結構的ArrayBlockingQueue要比LinkedBlockingQueue緊湊,因為其不需要創建所謂節點,但是其初始分配階段就需要一段連續的空間,所以初始內存需求更大。
- 通用場景中,LinkedBlockingQueue的吞吐量一般優於ArrayBlockingQueue,因為它實現了更加細粒度的鎖操作。
- ArrayBlockingQueue實現比較簡單,性能更好預測,屬於表現穩定的“選手”。
- 如果需要實現的是兩個線程之間接力性(handoff)的場景,可能會選擇CountDownLatch,但是SynchronousQueue也是完美符合這種場景的,而且線程間協調和數據傳輸統一起來,代碼更加規范。
- 可能令人意外的是,很多時候SynchronousQueue的性能表現,往往大大超過其他實現,尤其是在隊列元素較小的場景。