久久96国产精品久久久-久久发布国产伦子伦精品-久久精品国产精品青草-久久天天躁夜夜躁狠狠85麻豆

技術(shù)員聯(lián)盟提供win764位系統(tǒng)下載,win10,win7,xp,裝機(jī)純凈版,64位旗艦版,綠色軟件,免費(fèi)軟件下載基地!

當(dāng)前位置:主頁 > 教程 > 服務(wù)器類 >

java同步器SynchronousQueue詳解

來源:技術(shù)員聯(lián)盟┆發(fā)布時(shí)間:2017-10-01 12:33┆點(diǎn)擊:

學(xué)習(xí)以來對線程的操作有很大的改觀,從c/c++的mutex到j(luò)ava的各種鎖(當(dāng)然不是嫌麻煩,java讀寫鎖的實(shí)現(xiàn)還是帶來不少好處的,但是sokcet的設(shè)計(jì)我就不敢恭維了,tcp和udp是兩個(gè)類,弄得我現(xiàn)在對udp也不怎么熟悉)。其中最讓我感到特別剛需的設(shè)計(jì)就是同步器,除了countdownlatch,剩下的都比較剛需,cyclicbarrier我現(xiàn)在唯一能感覺他的好用處就是循環(huán)打印a,b,exchanger和SynchronousQueue我一直沒發(fā)現(xiàn)什么作用,兩個(gè)就適合生產(chǎn)者消費(fèi)者問題。以上就是四大同步器,聽說過2個(gè)以上的就很厲害了,有些場合太難想了。

場景思路

這次說最后兩個(gè)用的場景吧,我要做的事情呢,是采集一堆數(shù)據(jù),然后采集另外的數(shù)據(jù)綜合處理,但是兩個(gè)數(shù)據(jù)是和時(shí)間相關(guān)的,如果順序執(zhí)行的話,那么處理結(jié)果的可信度越低,最初的設(shè)想就是利用異步處理,兩個(gè)數(shù)據(jù)采集同時(shí)進(jìn)行,然后一起處理,futuretask,就作為首選,我的采集信息還是周期性的任務(wù),必需要用定時(shí)的線程池了,但是這種線程池(別說timer,這個(gè)類更建議用線程池替換)并沒有為異步處理做返回值,我也沒辦法直接獲取處理的數(shù)據(jù)了,無奈的情況下只能用線程來做了,同時(shí)也必須要用同步器來同步了,用手動阻塞線程然后喚醒這個(gè)行為實(shí)在是太不可取了,你全喚醒了,可能造成不該運(yùn)行的代碼開始運(yùn)行,喚醒單個(gè),還得看cpu的調(diào)度,于是想到了exchanger和SynchronousQueue,我最終選取了SynchronousQueue。

SynchronousQueue

其實(shí)就是特殊的阻塞隊(duì)列,特殊就特殊在他最多放一個(gè)元素,而且這個(gè)元素不在特定的時(shí)間消費(fèi)掉就沒了,而且永遠(yuǎn)長度都是0,具體看api就發(fā)現(xiàn)能用的方法沒幾個(gè),3個(gè)是放入,2個(gè)是取走。

demo

生產(chǎn)者,消息最多存放1分鐘

public void run() { try { queue.offer(i++,1,TimeUnit.MINUTES); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("add"); }

消費(fèi)者

System.out.println(queue.poll(1,TimeUnit.SECONDS));

用了這個(gè)同步器,這種定時(shí)生產(chǎn)者消費(fèi)者問題,代碼量就很少,不需要自己再寫同步的代碼了。也避免了最初喚醒阻塞帶來的不可預(yù)估性。