Java線程池隊(duì)列LinkedTransferQueue示例詳解
正文
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"); }
LinkedTransferQueue
無(wú)界阻塞隊(duì)列LinkedTransferQueue,此隊(duì)列也是基于鏈表實(shí)現(xiàn),對(duì)于所有給定的元素都是先入先出的。LinkedTransferQueue可以算是 LinkedBolckingQueue 和 SynchronousQueue 的合體。SynchronousQueue 內(nèi)部無(wú)法存儲(chǔ)元素,當(dāng)要添加元素的時(shí)候,需要阻塞。
LinkedBolckingQueue 則內(nèi)部使用了大量的鎖,性能有所下降。
public class LinkedTransferQueue<E> extends AbstractQueue<E> implements TransferQueue<E>, java.io.Serializable {
相對(duì)于其他阻塞隊(duì)列,LinkedTransferQueue多了 tryTransfer(E e)和transfer(E e) 方法。
public interface TransferQueue<E> extends BlockingQueue<E> { // 如果可能,立即將元素轉(zhuǎn)移給等待的消費(fèi)者。 // 更確切地說(shuō),如果存在消費(fèi)者已經(jīng)等待接收它(在 take 或 timed poll(long,TimeUnit)poll)中,則立即傳送指定的元素,否則返回 false。 boolean tryTransfer(E e); // 將元素轉(zhuǎn)移給消費(fèi)者,如果需要的話等待。 // 更準(zhǔn)確地說(shuō),如果存在一個(gè)消費(fèi)者已經(jīng)等待接收它(在 take 或timed poll(long,TimeUnit)poll)中,則立即傳送指定的元素,否則等待直到元素由消費(fèi)者接收。 void transfer(E e) throws InterruptedException; // 上面方法的基礎(chǔ)上設(shè)置超時(shí)時(shí)間 boolean tryTransfer(E e, long timeout, TimeUnit unit) throws InterruptedException; // 如果至少有一位消費(fèi)者在等待,則返回 true boolean hasWaitingConsumer(); // 返回等待消費(fèi)者人數(shù)的估計(jì)值 int getWaitingConsumerCount(); }
LinkedTransferQueue 消費(fèi)者線程獲取取數(shù)據(jù)時(shí):調(diào)用take poll 等方法
如果隊(duì)列不為空,則直接取走數(shù)據(jù),若隊(duì)列為空則消費(fèi)者線程會(huì)生成一個(gè)占位虛擬節(jié)點(diǎn)(節(jié)點(diǎn)元素為null)入隊(duì),并等待在這個(gè)節(jié)點(diǎn)上,后面生產(chǎn)者線程請(qǐng)求添加數(shù)據(jù)時(shí),會(huì)從單向鏈表的head節(jié)點(diǎn)開(kāi)始遍歷,如果發(fā)現(xiàn)某個(gè)節(jié)點(diǎn)是一個(gè)取數(shù)請(qǐng)求任務(wù)類型的節(jié)點(diǎn)(即是這個(gè)節(jié)點(diǎn)的isData為false,item == null),生產(chǎn)者線程就不入隊(duì)了,直接就將元素填充到該節(jié)點(diǎn)(元素傳遞給它),并喚醒該節(jié)點(diǎn)等待的消費(fèi)者線程,被喚醒的消費(fèi)者線程取走元素。
tryTransfer(E e)方法
tryTransfer(E e) 當(dāng)生產(chǎn)者線程調(diào)用tryTransfer方法時(shí),如果沒(méi)有消費(fèi)者等待接收元素,則會(huì)立即返回false。該方法和transfer方法的區(qū)別就是tryTransfer方法無(wú)論消費(fèi)者是否接收,方法立即返回,而transfer方法必須等到消費(fèi)者消費(fèi)后才返回。
tryTransfer(E e, long timeout, TimeUnit unit) 加上了限時(shí)等待功能,如果沒(méi)有消費(fèi)者消費(fèi)該元素,則等待指定的時(shí)間再返回;如果超時(shí)還沒(méi)消費(fèi)元素,則返回false,如果在超時(shí)時(shí)間內(nèi)消費(fèi)了元素,則返回true。
transfer(E e)方法
transfer方法,用于將指定元素e傳遞給消費(fèi)者線程(調(diào)用take/poll方法)。如果有消費(fèi)者線程正在阻塞等待,則調(diào)用transfer方法的線程會(huì)直接將元素傳遞給它;
如果沒(méi)有消費(fèi)者線程等待獲取元素,則調(diào)用transfer方法的線程會(huì)將元素插入到隊(duì)尾,然后阻塞等待,直到出現(xiàn)一個(gè)消費(fèi)者線程獲取元素。
以上就是Java線程池隊(duì)列LinkedTransferQueue示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Java LinkedTransferQueue的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Mybatis 中的一對(duì)一,一對(duì)多,多對(duì)多的配置原則示例代碼
這篇文章主要介紹了 Mybatis 中的一對(duì)一,一對(duì)多,多對(duì)多的配置原則示例代碼,需要的朋友可以參考下2017-03-03Spring Boot設(shè)置支持跨域請(qǐng)求過(guò)程詳解
這篇文章主要介紹了Spring Boot設(shè)置支持跨域請(qǐng)求過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08Java中的Map集合根據(jù)key值排序的實(shí)現(xiàn)
本文主要介紹了Java中的Map集合如何根據(jù)key值排序,包含使用TreeMap和使用lambda表達(dá)式和Stream流兩種方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03Java中的CopyOnWriteArrayList你了解嗎
CopyOnWriteArrayList是Java集合框架中的一種線程安全的List實(shí)現(xiàn),這篇文章主要來(lái)和大家聊聊CopyOnWriteArrayList的簡(jiǎn)單使用,需要的可以參考一下2023-06-06Spring動(dòng)態(tài)添加定時(shí)任務(wù)的實(shí)現(xiàn)思路
這篇文章主要介紹了Spring動(dòng)態(tài)添加定時(shí)任務(wù)的實(shí)現(xiàn)思路,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07spring cloud config分布式配置中心的高可用問(wèn)題
本文給大家介紹spring cloud config分布式配置中心的高可用問(wèn)題,通過(guò)整合Eureka來(lái)實(shí)現(xiàn)配置中心的高可用,需要的朋友參考下本文2018-01-01