Java線程池隊(duì)列PriorityBlockingQueue和SynchronousQueue詳解
正文
public enum QueueTypeEnum { ARRAY_BLOCKING_QUEUE(1, "ArrayBlockingQueue"), LINKED_BLOCKING_QUEUE(2, "LinkedBlockingQueue"), DELAY_QUEUE(3, "DelayQueue"), PRIORITY_BLOCKING_QUEUE(4, "PriorityBlockingQueue"), SYNCHRONOUS_QUEUE(5, "SynchronousQueue"), LINKED_TRANSFER_QUEUE(6, "LinkedTransferQueue"), LINKED_BLOCKING_DEQUE(7, "LinkedBlockingDeque"), VARIABLE_LINKED_BLOCKING_QUEUE(8, "VariableLinkedBlockingQueue"), MEMORY_SAFE_LINKED_BLOCKING_QUEUE(9, "MemorySafeLinkedBlockingQueue"); }
PriorityBlockingQueue阻塞優(yōu)先隊(duì)列
一個(gè)支持優(yōu)先級(jí)排序的無(wú)界阻塞隊(duì)列;對(duì)元素沒(méi)有要求,可以實(shí)現(xiàn)Comparable接口也可以提供 Comparator來(lái)對(duì)隊(duì)列中的元素進(jìn)行比較。通過(guò)構(gòu)造函數(shù)傳入的對(duì)象來(lái)判斷,傳入的對(duì)象必須實(shí)現(xiàn)comparable接口,并重寫(xiě)compareTo方法。可以按照自然排序或自定義排序的順序在隊(duì)列中對(duì)元素進(jìn)行排序。
例如新建對(duì)象Person:
public class Person implements Comparable<Person>{ private int id; @Override public int compareTo(Person person) { return this.id > person.getId() ? 1 : ( this.id < person.getId() ? -1 :0); } }
每次添加一個(gè)元素,PriorityBlockingQueue中的person都會(huì)執(zhí)行compareTo方法進(jìn)行排序,但是只是把第一個(gè)元素排在首位,其他元素按照隊(duì)列的一系列復(fù)雜算法排序。這就保障了每次獲取到的元素都是經(jīng)過(guò)排序的第一個(gè)元素。
SynchronousQueue
SynchronousQueue是一個(gè)不存儲(chǔ)元素的阻塞隊(duì)列,是BlockingQueue的一種,SynchronousQueue線程安全的。SynchronousQueue和其他的BlockingQueue不同的是SynchronousQueue的capacity是0。即SynchronousQueue不存儲(chǔ)任何元素。消費(fèi)者線程調(diào)用 take() 方法的時(shí)候就會(huì)發(fā)生阻塞,直到有一個(gè)生產(chǎn)者線程生產(chǎn)了一個(gè)元素,消費(fèi)者線程就可以拿到這個(gè)元素并返回;生產(chǎn)者線程調(diào)用 put() 方法的時(shí)候也會(huì)發(fā)生阻塞,直到有一個(gè)消費(fèi)者線程消費(fèi)了一個(gè)元素,生產(chǎn)者才會(huì)返回。
SynchronousQueue內(nèi)部并沒(méi)有數(shù)據(jù)緩存空間,你不能調(diào)用peek()方法來(lái)看隊(duì)列中是否有數(shù)據(jù)元素,因?yàn)閿?shù)據(jù)元素只有當(dāng)你試著取走的時(shí)候才可能存在,不取走而只想偷 窺一下是不行的,當(dāng)然遍歷這個(gè)隊(duì)列的操作也是不允許的。
隊(duì)列頭元素是第一個(gè)排隊(duì)要插入數(shù)據(jù)的線程,而不是要交換的數(shù)據(jù)。數(shù)據(jù)是在配對(duì)的生產(chǎn)者和消費(fèi)者線程之間直接傳遞的,并不會(huì)將數(shù)據(jù)緩沖到隊(duì)列中??梢赃@樣來(lái)理解:生產(chǎn)者和消費(fèi)者互相等待對(duì)方,握手,然后一起離開(kāi)。
SynchronousQueue的一個(gè)使用場(chǎng)景是在線程池里。Executors.newCachedThreadPool()就使用了SynchronousQueue,這個(gè)線程池根據(jù)需要(新任務(wù)到來(lái)時(shí))創(chuàng)建新的線程,如果有空閑線程則會(huì)重復(fù)使用,線程空閑了60秒后會(huì)被回收?!?/p>
以上就是Java線程池隊(duì)列PriorityBlockingQueue和SynchronousQueue詳解的詳細(xì)內(nèi)容,更多關(guān)于Java線程池隊(duì)列的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java8中用foreach循環(huán)獲取對(duì)象的index下標(biāo)詳解
這篇文章主要給大家介紹了關(guān)于Java8中用foreach循環(huán)獲取對(duì)象的index下標(biāo)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04SharedWorkerGlobalScope屬性數(shù)據(jù)共享示例解析
這篇文章主要為大家介紹了SharedWorkerGlobalScope屬性數(shù)據(jù)共享示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12idea創(chuàng)建springboot項(xiàng)目(版本只能選擇17和21)的解決方法
idea2023創(chuàng)建spring boot項(xiàng)目時(shí),java版本無(wú)法選擇11,本文主要介紹了idea創(chuàng)建springboot項(xiàng)目(版本只能選擇17和21),下面就來(lái)介紹一下解決方法,感興趣的可以了解一下2024-01-01SpringCloud及Nacos服務(wù)注冊(cè)IP選擇問(wèn)題解決方法
這篇文章主要介紹了SpringCloud及Nacos服務(wù)注冊(cè)IP選擇問(wèn)題,為什么注冊(cè)的IP和真實(shí)IP不符合呢,原因是Nacos客戶端在注冊(cè)服務(wù)時(shí)會(huì)從機(jī)器網(wǎng)卡中選擇一個(gè)IP來(lái)注冊(cè),所以,當(dāng)注冊(cè)了的是非真實(shí)IP后,另一臺(tái)機(jī)器調(diào)用時(shí)是不可能調(diào)通的,知道問(wèn)題原因就是解決方法,一起看看吧2024-01-01springboot2.0 配置時(shí)間格式化不生效問(wèn)題的解決
這篇文章主要介紹了springboot2.0 配置時(shí)間格式化不生效問(wèn)題的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09java循環(huán)刪除List元素報(bào)錯(cuò)的原因分析與解決
大家在工作中應(yīng)該都會(huì)遇到從List集合中刪除某一個(gè)或多個(gè)元素的業(yè)務(wù)場(chǎng)景,相信大家都會(huì)避開(kāi)在循環(huán)里面刪除元素,使用其他方式處理,這是為什么呢,下面小編就來(lái)和大家詳細(xì)聊聊2023-11-11