Java多線程中的Phaser詳解
什么是Phaser
Pahser是一個可以重復(fù)使用的同步屏障,Phaser是按照不同階段執(zhí)行線程的,就像是結(jié)合了CountDownLatch和CyclicBarrier,它本身維護(hù)著一個叫 phase 的成員變量代表當(dāng)前執(zhí)行的階段。(可以這么理解:CyclicBarrier是只有一個柵欄,Phaser是縱向好幾個柵欄,每個柵欄觸發(fā)時可以有不同的操作.)
關(guān)鍵方法
- onAdvance() ,一般會自定義一個類繼承Phaser,并重寫onAdvance方法.每次parties到達(dá)相位后,會調(diào)用onAdvance方法,處理自己的業(yè)務(wù)邏輯;
- bulkRegister(int parties),批量注冊parties,有點(diǎn)類似于CountdownLatch的倒數(shù)計數(shù)的初始化;
- arriveAndAwaitAdvance(),各parties準(zhǔn)備就緒后到達(dá)相位,等待其他parties后才繼續(xù)執(zhí)行,注意下一次相位仍會參與;
- arriveAndDeregister(),到達(dá)這個相位,并且從中注銷,不需等其他parties到達(dá)就可繼續(xù)執(zhí)行,不再參與Phaser規(guī)則了;
應(yīng)用場景
以簡單的結(jié)婚流程為例:
- 新郎,新娘,親朋好友到達(dá)現(xiàn)場。
- 所有人吃完宴席。
- 所有人離開。
- 新郎新娘入洞房。
代碼示例:
public class TestPhaser { static Random r = new Random(); static MarriagePhaser phaser = new MarriagePhaser(); static void milliSleep(int milli) { try { TimeUnit.MILLISECONDS.sleep(milli); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { phaser.bulkRegister(7); for(int i=0; i<5; i++) { new Thread(new Person("p" + i)).start(); } new Thread(new Person("新郎")).start(); new Thread(new Person("新娘")).start(); } static class MarriagePhaser extends Phaser { @Override protected boolean onAdvance(int phase, int registeredParties) { switch (phase) { case 0: System.out.println("所有人到齊了!" + registeredParties); System.out.println(); return false; case 1: System.out.println("所有人吃完了!" + registeredParties); System.out.println(); return false; case 2: System.out.println("所有人離開了!" + registeredParties); System.out.println(); return false; case 3: System.out.println("婚禮結(jié)束!新郎新娘抱抱!" + registeredParties); return true; default: return true; } } } static class Person implements Runnable { String name; public Person(String name) { this.name = name; } public void arrive() { milliSleep(r.nextInt(1000)); System.out.printf("%s 到達(dá)現(xiàn)場!\n", name); phaser.arriveAndAwaitAdvance(); } public void eat() { milliSleep(r.nextInt(1000)); System.out.printf("%s 吃完!\n", name); phaser.arriveAndAwaitAdvance(); } public void leave() { milliSleep(r.nextInt(1000)); System.out.printf("%s 離開!\n", name); phaser.arriveAndAwaitAdvance(); } private void hug() { if(name.equals("新郎") || name.equals("新娘")) { milliSleep(r.nextInt(1000)); System.out.printf("%s 洞房!\n", name); phaser.arriveAndAwaitAdvance(); } else { phaser.arriveAndDeregister(); } } @Override public void run() { arrive(); eat(); leave(); hug(); } } }
到此這篇關(guān)于Java多線程中的Phaser詳解的文章就介紹到這了,更多相關(guān)Phaser詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java利用遞歸算法實(shí)現(xiàn)查詢斐波那契數(shù)
今天小編就為大家分享一篇關(guān)于Java利用遞歸算法實(shí)現(xiàn)查詢斐波那契數(shù),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12Java Floyd算法求有權(quán)圖(非負(fù)權(quán))的最短路徑并打印
這篇文章主要介紹了Java Floyd算法求有權(quán)圖(非負(fù)權(quán))的最短路徑并打印,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07解決BigDecimal轉(zhuǎn)long丟失精度的問題
這篇文章主要介紹了解決BigDecimal轉(zhuǎn)long丟失精度的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12redis實(shí)現(xiàn)分布式鎖實(shí)例詳解
這篇文章主要為大家詳細(xì)介紹了redis實(shí)現(xiàn)分布式鎖實(shí)例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03Java中的三種標(biāo)準(zhǔn)注解和四種元注解說明
這篇文章主要介紹了Java中的三種標(biāo)準(zhǔn)注解和四種元注解說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02Java依賴倒轉(zhuǎn)原則_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java依賴倒轉(zhuǎn)原則的定義及問題由來解決方案,感興趣的朋友一起看看吧2017-08-08