如何在Java中利用CyclicBarrier實(shí)現(xiàn)并發(fā)編程?很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
創(chuàng)新互聯(lián)長期為1000多家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為寧德企業(yè)提供專業(yè)的成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作,寧德網(wǎng)站改版等技術(shù)服務(wù)。擁有十多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。
使用JAVA編寫并發(fā)程序的時(shí)候,我們需要仔細(xì)去思考一下并發(fā)流程的控制,如何讓各個(gè)線程之間協(xié)作完成某項(xiàng)工作。有時(shí)候,我們啟動(dòng)N個(gè)線程去做一件事情,只有當(dāng)這N個(gè)線程都達(dá)到某一個(gè)臨界點(diǎn)的時(shí)候,我們才能繼續(xù)下面的工作,就是說如果這N個(gè)線程中的某一個(gè)線程先到達(dá)預(yù)先定義好的臨界點(diǎn),它必須等待其他N-1線程也到達(dá)這個(gè)臨界點(diǎn),接下來的工作才能繼續(xù),只要這N個(gè)線程中有1個(gè)線程沒有到達(dá)所謂的臨界點(diǎn),其他線程就算搶先到達(dá)了臨界點(diǎn),也只能等待,只有所有這N個(gè)線程都到達(dá)臨界點(diǎn)后,接下來的事情才能繼續(xù)。
一、場景描述
有四個(gè)游戲玩家玩游戲,游戲有三個(gè)關(guān)卡,每個(gè)關(guān)卡必須要所有玩家都到達(dá)后才能允許通過。其實(shí)這個(gè)場景里的玩家中如果有玩家A先到了關(guān)卡1,他必須等到其他所有玩家都到達(dá)關(guān)卡1時(shí)才能通過,也就是說線程之間需要相互等待。這和CountDownLatch的應(yīng)用場景有區(qū)別,CountDownLatch里的線程是到了運(yùn)行的目標(biāo)后繼續(xù)干自己的其他事情,而這里的線程需要等待其他線程后才能繼續(xù)完成下面的工作。
二、CyclicBarrier介紹
CyclicBarrier 的字面意思是可循環(huán)使用(Cyclic)的屏障(Barrier)。它要做的事情是,讓一組線程到達(dá)一個(gè)屏障(也可以叫同步點(diǎn))時(shí)被阻塞,直到最后一個(gè)線程到達(dá)屏障時(shí),屏障才會(huì)開門,所有被屏障攔截的線程才會(huì)繼續(xù)干活。CyclicBarrier默認(rèn)的構(gòu)造方法是CyclicBarrier(int parties),其參數(shù)表示屏障攔截的線程數(shù)量,每個(gè)線程調(diào)用await方法告訴CyclicBarrier我已經(jīng)到達(dá)了屏障,然后當(dāng)前線程被阻塞。
CyclicBarrier類有兩個(gè)常用的構(gòu)造方法:
1. CyclicBarrier(int parties)
這里的parties也是一個(gè)計(jì)數(shù)器,例如,初始化時(shí)parties里的計(jì)數(shù)是3,于是擁有該CyclicBarrier對象的線程當(dāng)parties的計(jì)數(shù)為3時(shí)就喚醒,注:這里parties里的計(jì)數(shù)在運(yùn)行時(shí)當(dāng)調(diào)用CyclicBarrier:await()時(shí),計(jì)數(shù)就加1,一直加到初始的值
2. CyclicBarrier(int parties, Runnable barrierAction)
這里的parties與上一個(gè)構(gòu)造方法的解釋是一樣的,這里需要解釋的是第二個(gè)入?yún)?Runnable barrierAction),這個(gè)參數(shù)是一個(gè)實(shí)現(xiàn)Runnable接口的類的對象,也就是說當(dāng)parties加到初始值時(shí)就出發(fā)barrierAction的內(nèi)容。
代碼示例
package com.itmyhome; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * 玩家類 * @author itmyhome * */ class Player implements Runnable { private CyclicBarrier cyclicBarrier; private int id; public Player(int id, CyclicBarrier cyclicBarrier) { this.cyclicBarrier = cyclicBarrier; this.id = id; } @Override public void run() { try { System.out.println("玩家" + id + "正在玩第一關(guān)..."); cyclicBarrier.await(); System.out.println("玩家" + id + "進(jìn)入第二關(guān)..."); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } } public class CyclicBarrierTest { public static void main(String[] args) { // CyclicBarrier cyclicBarrier = new CyclicBarrier(4); CyclicBarrier cyclicBarrier = new CyclicBarrier(4, new Runnable() { @Override public void run() { System.out.println("所有玩家進(jìn)入第二關(guān)!"); } }); for (int i = 0; i < 4; i++) { new Thread(new Player(i, cyclicBarrier)).start(); } } }
輸出結(jié)果:
玩家0正在玩第一關(guān)... 玩家3正在玩第一關(guān)... 玩家2正在玩第一關(guān)... 玩家1正在玩第一關(guān)... 所有玩家進(jìn)入第二關(guān)! 玩家3進(jìn)入第二關(guān)... 玩家1進(jìn)入第二關(guān)... 玩家2進(jìn)入第二關(guān)... 玩家0進(jìn)入第二關(guān)...
CyclicBarrier和CountDownLatch的區(qū)別
CountDownLatch: 一個(gè)線程(或者多個(gè)), 等待另外N個(gè)線程完成某個(gè)事情之后才能執(zhí)行。
CyclicBarrier: N個(gè)線程相互等待,任何一個(gè)線程完成之前,所有的線程都必須等待。
CountDownLatch的計(jì)數(shù)器只能使用一次。而CyclicBarrier的計(jì)數(shù)器可以使用reset() 方法重置。所以CyclicBarrier能處理更為復(fù)雜的業(yè)務(wù)場景,比如如果計(jì)算發(fā)生錯(cuò)誤,可以重置計(jì)數(shù)器,并讓線程們重新執(zhí)行一次。
CountDownLatch:減計(jì)數(shù)方式,CyclicBarrier:加計(jì)數(shù)方式
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。
當(dāng)前標(biāo)題:如何在Java中利用CyclicBarrier實(shí)現(xiàn)并發(fā)編程
URL鏈接:http://jinyejixie.com/article8/gggcip.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、微信公眾號(hào)、移動(dòng)網(wǎng)站建設(shè)、微信小程序、建站公司、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)