聊聊java中那些各式各樣的queue

1:概述

隊列真的是一個很是nice的數據結構,有序,規則,能夠給與緩衝,就像人們心中那種秩序社會同樣,那麼這期小威哥就來粗淺的聊聊java中那些常見的queue。java



2:各類常見queue對比

2.1:對比表格

隊列 數據結構 邊界 併發特徵 特色
ArrayBlockingQueue 數組 有界(由於是數組) 阻塞 簡單,數組結構
LinkedBlockingQueue 鏈表 能夠指定大小(默認爲MaxInt) 阻塞 鏈表
ConcurrentLinkedQueue 鏈表 無界 cas無鎖 無鎖,多消費者
DelayQueue 無界 阻塞 實現延時效果

2.2:有界無界,併發性

  • 有界無界性實質就是指一個隊列是否支持無限制的塞東西,這就和數據結構有關了,好比名字帶array的基本就是個數組,數組確定是要指定它的大小的,都是有邊界的。而帶有link這種一看就知道是鏈表,那麼節點能夠無限掛(只要內存夠),不過像LinkedBlockingQueue仍是會指定一個最大掛載量的防止內存boom!!redis

  • 這些隊列容器的話其實都是支持併發的,只是效率高低問題,帶bloking的顧名思義就是阻塞了,而帶concurrent的隊列就是使用cas樂觀鎖去實現無鎖競爭了。spring

2.3:使用場景選擇

  • 能夠預估隊列有界,能夠選擇ArrayBlockingQueue
  • 單生產者,單消費者 用 LinkedBlockingqueue
  • 多生產者,單消費者 用 LinkedBlockingqueue
  • 單生產者 ,多消費者 用 ConcurrentLinkedQueue
  • 多生產者 ,多消費者 用 ConcurrentLinkedQueue
  • 若是是有延時效果,能夠選 DelayQueue

3:ConcurrentLinkedQueue的一個坑

ConcurrentLinkedQuene的size方法請千萬不要使用!!!!最好用isEmpty來代替,由於size方法會去遍歷鏈表節點來肯定size 數據庫

源碼以下:編程

4:Disruptor環形隊列

Disruptor隊列是一個次世代的環形jvm隊列,效率很是高,被log4j2所使用,關於這點能夠看個人另外一篇文章Disruptor隊列,這裏就再也不贅述了。api

5:分佈式消息隊列

固然,咱們如今的不少項目或者應用都是大規模的使用了分佈式的服務,不論redis,dubbo,springcloud,等等。因此不少jvm的內存隊列其實知足不了咱們的需求,這個時候咱們就須要使用分佈式的消息隊列。數組

這裏我推薦使用三個分佈式消息隊列緩存

  • redis : 大多數人覺得redis只是一個緩存kv數據庫,其實redis可使用監聽的功能實現一個很是輕量級的消息隊列。

可是redis實現的消息隊列沒法實現持久化,因此萬一斷電就丟了,因此建議若是傳輸一些可有可無的埋點啊什麼統計數據啊可使用一下。 數據結構

  • rocketmq:阿里出品的很是全面的消息隊列,api也很友好,推薦使用,記得須要關注業務冪等哦!!
  • kafka:劃時代的消息隊列,引領了目前的消息隊列潮流,超高的吞吐量,很適合廣告,流式處理啊,日誌記錄啊等等高吞吐場景。可是若是是金融等高可靠性的場景仍是使用rocketmq而且同步刷盤!

6:總結

隊列真的是一種萬金油,簡單易用並且使用場景豐富,可延時,可削峯,可異步,融合編程的不少經典又精髓的感念,是開發過程當中的利器!你們要多多合理使用!併發

相關文章
相關標籤/搜索