并發(fā)編程:并發(fā)容器,我們一起了解一下!
一、BlockingQueue
在所有的并發(fā)容器中,BlockingQueue是最常見(jiàn)的一種。BlockingQueue是一個(gè)帶阻塞功能的隊(duì)列,當(dāng)入隊(duì)列時(shí),若隊(duì)列已滿,則阻塞調(diào)用者;當(dāng)出隊(duì)列時(shí),若隊(duì)列為空,則阻塞調(diào)用者。
在Concurrent包中,BlockingQueue是一個(gè)接口,有許多個(gè)不同的實(shí)現(xiàn)類,如圖所示。
1、ArrayBlockingQueue是一個(gè)用數(shù)組實(shí)現(xiàn)的環(huán)形隊(duì)列,在構(gòu)造方法中,會(huì)要求傳入數(shù)組的容量。
2、LinkedBlockingQueue是一種基于單向鏈表的阻塞隊(duì)列。因?yàn)殛?duì)頭和隊(duì)尾是2個(gè)指針?lè)珠_(kāi)操作的, 所以用了2把鎖+2個(gè)條件,同時(shí)有1個(gè)AtomicInteger的原子變量記錄count數(shù)。
3、PriorityBlockingQueue 隊(duì)列通常是先進(jìn)先出的,而PriorityQueue是按照元素的優(yōu)先級(jí)從小到大出隊(duì)列的。正因?yàn)槿绱耍?PriorityQueue中的2個(gè)元素之間需要可以比較大小,并實(shí)現(xiàn)Comparable接口。
4、DelayQueue即延遲隊(duì)列,也就是一個(gè)按延遲時(shí)間從小到大出隊(duì)的PriorityQueue。所謂延遲時(shí)間, 就是“未來(lái)將要執(zhí)行的時(shí)間”減去“當(dāng)前時(shí)間”。為此,放入DelayQueue中的元素,必須實(shí)現(xiàn)Delayed接 口。
5、SynchronousQueue是一種特殊的BlockingQueue,它本身沒(méi)有容量。先調(diào)put(...),線程會(huì)阻塞; 直到另外一個(gè)線程調(diào)用了take(),兩個(gè)線程才同時(shí)解鎖,反之亦然。對(duì)于多個(gè)線程而言,例如3個(gè)線程, 調(diào)用3次put(...),3個(gè)線程都會(huì)阻塞;直到另外的線程調(diào)用3次take(),6個(gè)線程才同時(shí)解鎖,反之亦然。
二、BlockingDeque
BlockingDeque定義了一個(gè)阻塞的雙端隊(duì)列接口,如下所示。
該接口繼承了BlockingQueue接口,同時(shí)增加了對(duì)應(yīng)的雙端隊(duì)列操作接口。該接口只有一個(gè)實(shí)現(xiàn), 就是LinkedBlockingDeque。
三、CopyOnWrite
CopyOnWrite指在“寫”的時(shí)候,不是直接“寫”源數(shù)據(jù),而是把數(shù)據(jù)拷貝一份進(jìn)行修改,再通過(guò)悲觀鎖或者樂(lè)觀鎖的方式寫回。
那為什么不直接修改,而是要拷貝一份修改呢? 這是為了在“讀”的時(shí)候不加鎖。
1、CopyOnWriteArrayList
和ArrayList一樣,CopyOnWriteArrayList的核心數(shù)據(jù)結(jié)構(gòu)也是一個(gè)數(shù)組。
2、CopyOnWriteArraySet
CopyOnWriteArraySet 就是用 Array 實(shí)現(xiàn)的一個(gè) Set,保證所有元素都不重復(fù)。其內(nèi)部是封裝的一 個(gè)CopyOnWriteArrayList。