Java多線程CyclicBarrier的實(shí)現(xiàn)代碼
介紹
CyclicBarrier允許一組線程在到達(dá)某個(gè)柵欄點(diǎn)(common barrier point)互相等待,直到最后一個(gè)線程到達(dá)柵欄點(diǎn),柵欄才會(huì)打開,處于阻塞狀態(tài)的線程恢復(fù)繼續(xù)執(zhí)行。
1.就比如說我們?cè)诖蛲跽叩臅r(shí)候,十個(gè)人必須全部加載到100%,才可以開局。否則只要有一個(gè)人沒有加載到100%,那這個(gè)游戲就不能開始。先加載完成的玩家必須等待最后一個(gè)玩家加載成功才可以。
2.你可以想象長途客車,就算你是第一個(gè)上車的人,也要等待車滿才可以發(fā)車。否則車上所有人都要等待。
3.在百米賽跑里,比賽沒開始之前,每個(gè)運(yùn)動(dòng)員都在賽場上自由活動(dòng),有的熱身,有的喝水,有的跟教練談?wù)?。比賽快開始時(shí),準(zhǔn)備完畢的運(yùn)動(dòng)員就預(yù)備在起跑線上,如果有個(gè)運(yùn)動(dòng)員還沒準(zhǔn)備完(除去特殊情況),他們就一直等,直到運(yùn)動(dòng)員都在起跑線上,裁判喊口號(hào)后再開始跑。這里的起跑線就是屏障,做完準(zhǔn)備工作的運(yùn)動(dòng)員都等在起跑線,直到其他運(yùn)動(dòng)員也把準(zhǔn)備工作做完。
代碼介紹
接下來我們看看CyclicBarrier它的構(gòu)造器
//構(gòu)造器1 public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; } //構(gòu)造器2 public CyclicBarrier(int parties) { this(parties, null); }
CyclicBarrier有兩個(gè)構(gòu)造器,第一個(gè)構(gòu)造器是它的核心構(gòu)造器
參數(shù)1: 在這里你可以指定本局游戲的參與者數(shù)量(要攔截的線程數(shù))
參數(shù)2: 本局結(jié)束時(shí)要執(zhí)行的任務(wù),(也就是所有線程執(zhí)行完后執(zhí)行的線程)
CyclicBarrier供了兩種等待的方法,分別是定時(shí)等待和非定時(shí)等待。
參數(shù)1 : timeout 時(shí)間 , 參數(shù)2: 時(shí)間單位 TimeUnit.SECONDS (秒)
//非定時(shí)等待 (比如指定3個(gè)線程 每一個(gè)線程調(diào)用一次內(nèi)部count-- 當(dāng)count==0時(shí) 釋放3個(gè)線程 然后count重置為3 ) public int await() throws InterruptedException, BrokenBarrierException { try { return dowait(false, 0L); } catch (TimeoutException toe) { throw new Error(toe); } } //定時(shí)等待 (就是子一定時(shí)間內(nèi)如果還沒有 到時(shí)間自動(dòng)喚醒) public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException { return dowait(true, unit.toNanos(timeout)); }
重置屏障
將屏障重置到初始狀態(tài)。 如果任何一方目前正在barrier處等待,他們將返回一個(gè)BrokenBarrierException。 注意,由于其他原因發(fā)生破損后復(fù)位可能會(huì)比較復(fù)雜; 線程需要以其他方式重新同步,然后選擇一個(gè)執(zhí)行重置。 最好是為以后的使用創(chuàng)建一個(gè)新的障礙。
public void reset() { final ReentrantLock lock = this.lock; lock.lock(); try { breakBarrier(); // break the current generation nextGeneration(); // start a new generation } finally { lock.unlock(); } }
案例:王者榮耀游戲加載
public static void main(String[] args) throws InterruptedException { //設(shè)置這局游戲的唯一id 和人數(shù) CyclicBarrierUtils.initialize("da1",10,()->{ System.out.println("10人都加載完畢,進(jìn)入游戲"); }); //開始加載游戲 for (int i = 0; i < 10; i++) { int finalI = i; ExecutorUtils.create(()->{ System.out.println(finalI +":加載完畢,等待其他人...."); CyclicBarrierUtils.await("da1"); }); } }
代碼經(jīng)過二次封裝,所以看看邏輯就行
如有侵權(quán),請(qǐng)私信聯(lián)系我
到此這篇關(guān)于Java多線程CyclicBarrier的文章就介紹到這了,更多相關(guān)Java多線程CyclicBarrier內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mybatis執(zhí)行錯(cuò)誤但sql執(zhí)行正常問題
這篇文章主要介紹了mybatis執(zhí)行錯(cuò)誤但sql執(zhí)行正常問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01Spring Boot 2.x基礎(chǔ)教程之配置元數(shù)據(jù)的應(yīng)用
這篇文章主要介紹了Spring Boot 2.x基礎(chǔ)教程之配置元數(shù)據(jù)的應(yīng)用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01Java實(shí)戰(zhàn)之實(shí)現(xiàn)文件資料上傳并生成縮略圖
這篇文章主要介紹了通過Java實(shí)現(xiàn)文件資料的上傳并生成一個(gè)縮略圖,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,感興趣的小伙伴可以了解一下2021-12-12