一、概念
佇列:先進者先出。與棧一樣,也是一種受限的線性表,同樣有兩個基本操作:入隊和出隊。
二、佇列實現
佇列有兩種實現方式:順序佇列和鏈式佇列。
順序佇列
用陣列實現的佇列叫作順序佇列。
需要兩個指標:head指標和
tail
指標,分別指向隊頭和隊尾。
隨著入隊和出隊操作,head和
tail
會移到最右邊,即便還有空閒空間,也不通用再入隊了。這時候要用資料搬移。在入隊時,把資料陣列前端移動。
// 用陣列實現的隊列鏈式佇列public class arrayqueue
// 入隊
public bool enqueue(string item)
// 搬移完之後重新更新head和tail
tail -= head;
head = 0;
}items[tail] = item;
++tail;
return true;
}// 出隊
public string dequeue()
}
用鍊錶實現的佇列叫作鏈式佇列。
需要兩個指標:head指標和
tail
指標,分別指向鍊錶第乙個結點和最後乙個結點。
// 入隊
public bool enqueue(string item)
// 第一次入隊
if (head == null || tail == null)
else
--n;
return true;
}// 出隊
public string dequeue()
public class mylinkedlistnode
public string data
public mylinkedlistnode next }}
迴圈佇列
上面的陣列實現,在tail==n時,會有資料搬移操作,這樣入隊操作效能就會受到影響。
迴圈佇列是一種特殊的佇列,長得像個環,原來陣列是有頭有尾的,是一條直線,現在把首尾相連,形成乙個環,如下圖:
佇列空的條件:head==tail
佇列滿的條件:(tail+1)%n=head
public class circularqueue注:迴圈佇列的關鍵要確定好隊空和隊滿的判定條件。// 入隊
public bool enqueue(string item)
// 出隊
public string dequeue()
}
三、阻塞佇列和併發佇列
阻塞佇列就是在佇列基礎上增加了阻塞操作。簡單來說,就是在隊列為空的時候,從隊頭取資料會被阻塞。
可以使用阻塞佇列來實現「生產者
-消費者模型」。
通過協調「生產者」和
「消費者
」的個數,來提高資料的處理效率。
併發佇列就是要求執行緒安全的佇列。通過在enqueue()和
dequeue()
方法上加鎖。
四、執行緒池實現
有兩種處理策略。
1、非阻塞的處理方式,直接拒絕任務請求。
2、阻塞的處理方式,將請求排除,等有空閒執行緒時,取出請求繼續處理。
而佇列有兩種實現方式:基於陣列和基於鍊錶。
基於鍊錶,可以實現乙個支援無限排除的無界佇列,但可能會導致響應時間過長,對於響應時間比較敏感的系統,不適合採用這種方式。
基於陣列實現的有界佇列,佇列的大小有限,超過佇列大小時會拒絕請求,但設定乙個合理的佇列大小是非常講究的,既不能太大,也不能太小而無法充分利用資源,發揮最大效能。
對於大部分資源有限的場景,當沒有空閒資源時,基本上都可以通過「佇列
」這種資料結構來實現請求排除。
五、課後思考
1. 除了執行緒池這種池結構會用到隊列排隊請求,你還知道有哪些類似的池結構或者場景中會用到隊列的排隊請求呢?
比如資料庫連續池、web應該的請求佇列等。
2. 今天講到併發隊列,關於如何實現無鎖併發隊列,網上有非常多的討論。對這個問題,你怎麼看呢?
在多執行緒高併發程式設計的時候,最關鍵的問題就是保證共享物件的安全訪問。通常是用synchronized 來處理,其實加鎖本質上是將併發轉變為序列來實現的,勢必會影響吞吐量。
而最高效的做法就是不加鎖,那就是cas,
compare and swap
即比較並替換,設計併發演算法時常用到的一種技術。
cas實現原理:cas有三個運算元:記憶體值
v、舊的預期值
a、要修改的值
b,當且僅當預期值
a和記憶體值
v相同時,將記憶體值修改為
b並返回
true
,否則什麼都不做並返回
false
。
資料結構 06佇列
只能在表的一端進行插入,另一端進行刪除,且具有先進先出原則的線性表稱為佇列。若用 s a1,a 2,a3 an s a 1,a 2,a 3,a n s a1 a2 a3 an 表示佇列,則 佇列常見的兩種操作 限定插入和刪除操作在表的兩端進行的線性表稱為雙端佇列。雙端佇列又可以分為 佇列基本操作用順...
資料結構和演算法之美 09 佇列
佇列 queue 先進者先出,這就是典型的 佇列 ps 無論順序佇列還是鏈式佇列,隊首指標指向佇列中第乙個元素,隊尾指標指向佇列的最後乙個元素的下乙個位置。入隊時,現將元素入隊,再將隊尾指標後移一位。作為一種非常基礎的資料結構,佇列的應用也非常廣泛,特別是一些具有某些額外特性的佇列,比如迴圈佇列 阻...
資料結構與演算法之美06
個人學習筆記總結,詳見資料結構與演算法之美 度娘 線性表 非線性表 陣列 1 儲存結構 鏈式儲存,前驅後繼關聯 2 操作 crud 前後索引關聯,涉及最優最糟問題 特點 非常低效 查詢操作 了解其儲存方式,即查詢就是通過陣列下標進行。插入操作 假設陣列的長度為n,現在,如果我們需要將乙個資料插入到陣...