本篇文章為大家展示了阻塞隊(duì)列的綜合體LinkedTransferQueue如何理解,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
10年積累的成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有汕城免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
LinkedTransferQueue在某些實(shí)現(xiàn)可以看作是ConcurrentLinkedQueue、SynchronousQueue、LinkedBlockingQueue的超集,可以作為一個(gè)對(duì)比學(xué)習(xí)。
LinkedTransferQueue是一個(gè)由鏈表結(jié)構(gòu)組成的無界阻塞隊(duì)列,它實(shí)現(xiàn)了TransferQueue接口。TransferQueue接口繼承了BlockingQueue,主要擴(kuò)展了兩個(gè)方法tryTransfer、transfer。
BlockingQueue的put方法在隊(duì)列沒滿的時(shí)候是可以直接成功,不會(huì)阻塞線程,而TransferQueue擴(kuò)展的transfer方法會(huì)一直阻塞直到添加的數(shù)據(jù)被消費(fèi)者消費(fèi),這點(diǎn)與上一篇學(xué)的SynchronousQueue的put方法很相似,所以LinkedTransferQueue具有SynchronousQueue的功能。
LinkedTransferQueue的構(gòu)造方法比較簡(jiǎn)單,一個(gè)無參構(gòu)造方法,和一個(gè)接受一個(gè)集合的構(gòu)造方法,接受的集合就是把集合中的數(shù)據(jù)放到隊(duì)列中。并沒有初始化其他任何東西了。
與之前的阻塞隊(duì)列一樣也繼承了AbstractQueue所以有一些相同的方法,put、offer、add方法往隊(duì)列中添加數(shù)據(jù),由于隊(duì)列是無界隊(duì)列,所以這些方法一定會(huì)成功都不會(huì)阻塞。而take、poll方法消費(fèi)隊(duì)列中數(shù)據(jù),take方法可能會(huì)阻塞,poll有兩個(gè)方法可以直接返回、或者延時(shí)等待一段時(shí)間。
而它保存隊(duì)列的底層鏈表結(jié)構(gòu)是一個(gè)內(nèi)部類Node,主要屬性如下:
boolean isData:添加數(shù)據(jù)的方法創(chuàng)建的節(jié)點(diǎn)true,消費(fèi)為false;
Object item:item表示入隊(duì)的數(shù)據(jù),消費(fèi)方法為null
Node next:下一個(gè)節(jié)點(diǎn);
Thread waiter:阻塞的線程;
通過查看源碼發(fā)現(xiàn)put、offer、add、take、poll方法包括tryTransfer、transfer都是調(diào)用的xfer方法,所以我們重點(diǎn)分析xfer方法。
查看源碼前先解釋下方法參數(shù),方法”private E xfer(E e, boolean haveData, int how, long nanos)”,參數(shù)詳解如下:
e表示要添加的數(shù)據(jù),take與poll為null;
haveData表示是否有數(shù)據(jù),添加類方法為true,消費(fèi)類為false;
how表示方法阻塞方式,LinkedTransferQueue定義了4個(gè)靜態(tài)變量NOW、ASYNC、SYNC、TIMED,NOW表示不阻塞在poll、tryTransfer方法使用,ASYNC在put、offer、add方法使用,SYNC表示阻塞用于take方法,TIMED用于poll、tryTransfer的延時(shí)方法;
nanos表示最大阻塞多少時(shí)間,poll和tryTransfer方法會(huì)用到;
理解了方法參數(shù),接下來直接看源碼解析,如下圖:
主要流程分為兩步,首先是從現(xiàn)有鏈表中去匹配不相同的節(jié)點(diǎn),在所有的節(jié)點(diǎn)遍歷完成后都沒有匹配上再進(jìn)行后續(xù)處理,會(huì)根據(jù)傳入的how參數(shù)進(jìn)行判斷是否阻塞線程。
可以看到NOW會(huì)直接返回null(用于不阻塞的poll、tryTransfer),ASYNC會(huì)把節(jié)點(diǎn)加到鏈表中并返回(用于入隊(duì)系列方法),而其他的會(huì)調(diào)用awaitMatch方法會(huì)等待喚醒并返回結(jié)果。
代碼看起來比較復(fù)雜但是主流程實(shí)際上還是比較簡(jiǎn)單的,這里梳理了簡(jiǎn)要的主要流程如下圖:
LinkedTransferQueue由于是無界隊(duì)列所以不會(huì)阻塞生產(chǎn)者,它能提供LinkedBlockingQueue提供的功能,但是多一個(gè)transfer功能。
與SynchronousQueue的公平鎖實(shí)現(xiàn)相似,但是LinkedTransferQueue的生產(chǎn)者不會(huì)阻塞,而SynchronousQueue會(huì)不管是消費(fèi)者還是生產(chǎn)者都必須被消費(fèi)才能繼續(xù),也就是注重的是同步。
但是LinkedTransferQueue與SynchronousQueue都是通過CAS和循環(huán)實(shí)現(xiàn),而LinkedBlockingQueue是通過鎖來實(shí)現(xiàn)的。
上述內(nèi)容就是阻塞隊(duì)列的綜合體LinkedTransferQueue如何理解,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。