Java隊列學習第一篇之列介紹

Java隊列學習第一篇之列介紹

隊列大家都知道,但是在Java中隊列分哪幾種呢?清楚嗎?都有哪些地方用到了隊列呢?最常用的場景的就是消息中間件,比如各種MQ都是使用的隊列來的。如果沒有用過消息中間件,那麼線程池應該都知道吧。線程池也就是使用隊列的。還有redis也是基於隊列來實現的。學完本系列教程後,對隊列有了瞭解之後,才能更好的學習線程池相關的。所以本系列大家要好好學。

本文主要內容:為什麼會有隊列?隊列分類;隊列類圖關係。

本文出自凱哥Java(kaigejava)的《凱哥Java併發系列》之《Java併發編程之隊列》系列的第一篇:《Java隊列學習第一篇之隊列介紹》

一:為什麼會有隊列

隊列數據結構定義:

先來看看隊列數據結構的定義:隊列(Queue)是一種先進先出(first in first out:FIFO)的抽象的數據結構。對應我們日常生活中常見的是排隊買票、排查吃飯等場景。

隊列的實現方式

通常情況下,隊列的實現有兩種方式來實現的:數組和鏈表這兩種方式。

兩種方式的不同:

使用數據實現的隊列:我們知道,數組一般都要聲明數組的大小。通常是循環數組,隊列的大小受限於數組的大小。所以存在著天然的個數上限限制的。

數組的添加(插入)和獲取(取出)元素的時候,必須是從隊列的頭部和隊列尾部的指針進行判斷隊列是否已經滿了或者是空隊列操作的。

使用鏈表實現的隊列,就沒有數量的限制了。在插入元素的時候,直接連接在鏈表的尾部,需要取出元素的時候,直接從鏈表的頭部取出即可。

為什麼會有隊列呢?

為了解決現實生活中的問題(廢話嘛,軟件設計出來就是為了解決生活中的問題),雖然感覺是一句廢話,但是從側面說出了,我們學的不管是各種併發鎖還是Java基礎,都是從生活實際出發的。那麼,我們就來列舉生活中的例子來理解隊列。

在生活中,我們有時候會遇到這樣的場景:比如中午我們排隊去吃飯,等到你的時候,有可能有些飯菜沒有了,老闆會告訴你等幾分鐘,飯菜還在準備中。這種情況,你有可能選擇繼續等待著,等待著老闆把飯菜做好,你也可以選擇不等待老闆,對老闆說一聲你先去買瓶水或者是抽根菸,幹自己的事,直到老闆把飯菜做好後,再來就餐。

注意,這裡有兩個選擇操作:一個是等待著;一個是不等待。這兩個選擇對應我們Java中的算法分別是阻塞和非阻塞。

二: Java中隊列的分類

在併發編程中,有時候我們需要使用到隊列,而且是需要線程安全的隊列。那麼實現隊列有幾種方式呢?有兩種方式:一種是使用了阻塞算法的阻塞隊列(如上文中的吃飯的時候等待著老闆把飯菜做好);另一種是使用非阻塞算法(在老闆告知需要等待的時候,你去幹自己的事,等飯菜做好再來就餐)。

Java中阻塞算法的隊列實現方式可以用一個鎖,即入隊和出隊都是用同一把鎖來操作(可以理解為:排隊吃飯的時候從接待到做飯都是同一個人)的或者是使用不同的鎖。即入隊和出隊使用不同的鎖(可以理解為:排隊吃飯的時候,接待的人和做飯的人不是同一個)。

非阻塞隊列常用的有哪些?

常用的有三個:LinkedList、PriorityQueue和ConcurrentLinkedQueue.

沒有實現阻塞接口的LinkedList.實現了queue接口。類圖如下:

Java隊列學習第一篇之列介紹

實現了AbstractQueue的內置不堵塞隊列:PriorityQueue 和 ConcurrentLinkedQueue

類圖如下:

Java隊列學習第一篇之列介紹


兩者的區別:

Java隊列學習第一篇之列介紹


阻塞隊列常用的有哪些?

Java中阻塞隊列都是實現了BlockingQueue接口的。實現類如下圖:

Java隊列學習第一篇之列介紹


常有的有七個:ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、DelayQueue、SynchronousQueue、LinkedTransferQueue、LinkedBlockingDeque。

類圖:

Java隊列學習第一篇之列介紹


本文主要是對Java中隊列體系做了個簡介。在後面文章中凱哥(凱哥Java:kaigejava)將主要介紹阻塞隊列相關的。


分享到:


相關文章: