數據結構與算法:隊列:隊列在線程池等有限資源池中的應用

咱們都知道,CPU資源是有限的,任務的處理速度與線程個數並非線性正相關。相反,過多的線程反而會致使CPU頻繁切換,處理性能降低。因此線程池的大小通常都是綜合考慮要處理任務的特色和硬件環境,來事先設置的。算法

當咱們向固定大小的線程池中請求一個線程時,若是線程池中沒有空閒資源了,這個時候線程池如何處理這個請求?是拒絕請求仍是排隊請求?各類處理策略又是怎麼實現的呢?數據庫

實際上,這些問題並不複雜,其底層的數據結構就是咱們今天要了解的內容,隊列(queue)數組

1.什麼是隊列?

能夠把隊列想象成排隊買票,先來的先買,後來的人只能站末尾,不容許插隊。先進者先出,這就是典型的「隊列」安全

棧只支持兩個基本操做:入棧push()和出棧pop()。隊列和棧很是類似,支持的操做也頗有限,最基本的操做也是兩個入隊enqueue(),放一個數據到隊列尾部;出隊dequeue(),從隊列頭部取一個元素。數據結構

因此,隊列和棧同樣,也是一種操做受限的線性表數據結構。多線程


2.順序隊列和鏈式隊列

跟棧同樣,隊列能夠用數組實現,也能夠用鏈表來實現。用數組實現的隊列叫作順序隊列,用鏈表實現的隊列叫作鏈式隊列併發

3.循環隊列

顧名思義,循環隊列長得有點像一個環。本來數組是有頭有尾的,是一條直線。如今,咱們把首尾相連,扳成一個環。數據結構和算法

假如一個隊列大小爲8,當前隊頭指針head=4,隊尾指針tail=7,。當又有一個新的元素a入隊時,咱們放入下標爲7的位置,可是此時,tail不會更新爲8,而是會在環中後移一位,移到下標爲0的位置。經過這樣的操做,就能夠避免順序隊列進行操做會遇到的數據搬移操做。可是循環隊列的實現比較難,須要肯定好隊空和隊滿的斷定條件post

順序隊列中,隊滿的判斷條件是tail=n隊空的判斷條件是head=tail。那麼,針對循環隊列的話,如何判斷隊空和隊滿呢?性能

隊空的判斷條件仍然是head=tail,可是隊滿的判斷稍微有點複雜。隊滿的判斷條件是(tail+1)%n=head,當隊滿的時候,tail指向的位置沒有存儲數據的,所以,循環隊列會浪費一個數組存儲空間

4.阻塞隊列和併發隊列

阻塞隊列其實就是在隊列基礎上增長阻塞操做。在隊列爲空的時候,從隊頭取數據就會被阻塞。由於此時還沒有數據可取,直到隊列中有了數據才能返回;若是隊列滿了,那插入數據的操做就會被阻塞,直到隊列中有空閒位置再插入數據,而後再返回。

上述定義其實就是一個「生產者-消費者模型」。可使用阻塞隊列實現一個「生產者-消費者模型」。

基於阻塞隊列實現的「生產者-消費者模型」,能夠有效地協調生產和消費的速度。也能夠經過協調「生產者」和「消費者」的個數,來提升數據的處理效率


在多線程狀況下,會有多個線程同時操做隊列,這個時候,就會存在線程安全問題,如何實現一個線程安全的隊列呢?

線程安全的隊列叫作併發隊列。最簡單直接的實現方式是直接在enqueque()、dequeque()發佈方法上加鎖,可是鎖粒度大併發度會比較低同一時刻僅容許一個存或取操做。實際上,基於數組的循環隊列,利用CAS原子操做,能夠實現很是高效的併發隊列。這也是循環隊列比鏈式隊列應用更加普遍的緣由。

5.解答開篇

線程池沒有空閒線程時,新的任務請求線程資源時,線程池該如何處理?各類策略又是如何實現的呢?

通常有兩種處理策略。第一種是非阻塞的處理方式直接拒絕任務請求;另外一種是阻塞的處理方式,將請求排隊,等到有空閒線程時,取出排隊的請求去繼續處理。那麼,如何處理排隊的請求呢?

咱們但願公平地處理每一個排隊的請求,先進者先服務,因此隊列這種數據結構就很適合來存儲排隊的請求。

基於鏈表的鏈式隊列,能夠實現一個支持無限排隊無界隊列,可是可能會致使過多的請求排隊等待,請求處理的響應時間過長。因此,針對響應時間比較敏感的系統,基於鏈表實現的無限排隊的線程池是不合適的。

而基於數組實現有界隊列,隊列的大小有限,因此線程池中排隊的請求超過隊列大小時,接下來的請求就會被拒絕,這種方式對響應時間敏感的系統來講,就相對更加合理。不過,設置一個合理的隊列大小,也是很是講究的。隊列太大致使等待的請求太多,隊列過小會致使沒法充分利用系統資源,發揮最大性能。

除此以外,隊列能夠應用在任何有限資源池中,用於排隊請求,好比數據庫鏈接池等。實際上,對於大部分資源有限的場景,當沒有空閒資源時,基本均可以經過「隊列」這種數據結構來實現請求排隊。

6.內容小結

隊列最大的特色就是先進先出,主要的操做是入隊出隊。既能夠用數組實現,也能夠用鏈表實現。用數組實現的是順序隊列,用鏈表實現的叫鏈式隊列。還有一種像同樣的循環隊列。在數組實現隊列的時候,會有數據搬移的操做,要想解決數據搬移的問題,咱們就須要像環同樣的循環隊列

循環隊列的實現關鍵要肯定好隊空隊滿斷定條件

除此以外,還有幾種高級隊列,阻塞隊列併發隊列底層都是隊列這種數據結構,只不過是在之上附加了不少其餘功能阻塞隊列就是入隊、出隊操做能夠阻塞併發隊列就是隊列操做多線程安全


下一篇:數據結構和算法:遞歸

相關文章
相關標籤/搜索