Java多線程中的Phaser詳解
什么是Phaser
Pahser是一個(gè)可以重復(fù)使用的同步屏障,Phaser是按照不同階段執(zhí)行線程的,就像是結(jié)合了CountDownLatch和CyclicBarrier,它本身維護(hù)著一個(gè)叫 phase 的成員變量代表當(dāng)前執(zhí)行的階段。(可以這么理解:CyclicBarrier是只有一個(gè)柵欄,Phaser是縱向好幾個(gè)柵欄,每個(gè)柵欄觸發(fā)時(shí)可以有不同的操作.)
關(guān)鍵方法
- onAdvance() ,一般會(huì)自定義一個(gè)類繼承Phaser,并重寫(xiě)onAdvance方法.每次parties到達(dá)相位后,會(huì)調(diào)用onAdvance方法,處理自己的業(yè)務(wù)邏輯;
- bulkRegister(int parties),批量注冊(cè)parties,有點(diǎn)類似于CountdownLatch的倒數(shù)計(jì)數(shù)的初始化;
- arriveAndAwaitAdvance(),各parties準(zhǔn)備就緒后到達(dá)相位,等待其他parties后才繼續(xù)執(zhí)行,注意下一次相位仍會(huì)參與;
- arriveAndDeregister(),到達(dá)這個(gè)相位,并且從中注銷,不需等其他parties到達(dá)就可繼續(xù)執(zhí)行,不再參與Phaser規(guī)則了;
應(yīng)用場(chǎng)景
以簡(jiǎn)單的結(jié)婚流程為例:
- 新郎,新娘,親朋好友到達(dá)現(xiàn)場(chǎng)。
- 所有人吃完宴席。
- 所有人離開(kāi)。
- 新郎新娘入洞房。
代碼示例:
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("所有人離開(kāi)了!" + 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)場(chǎng)!\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 離開(kāi)!\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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java利用遞歸算法實(shí)現(xiàn)查詢斐波那契數(shù)
今天小編就為大家分享一篇關(guān)于Java利用遞歸算法實(shí)現(xiàn)查詢斐波那契數(shù),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12
Java Floyd算法求有權(quán)圖(非負(fù)權(quán))的最短路徑并打印
這篇文章主要介紹了Java Floyd算法求有權(quán)圖(非負(fù)權(quán))的最短路徑并打印,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
解決BigDecimal轉(zhuǎn)long丟失精度的問(wèn)題
這篇文章主要介紹了解決BigDecimal轉(zhuǎn)long丟失精度的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
redis實(shí)現(xiàn)分布式鎖實(shí)例詳解
這篇文章主要為大家詳細(xì)介紹了redis實(shí)現(xiàn)分布式鎖實(shí)例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03
Java中的三種標(biāo)準(zhǔn)注解和四種元注解說(shuō)明
這篇文章主要介紹了Java中的三種標(biāo)準(zhǔn)注解和四種元注解說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Java依賴倒轉(zhuǎn)原則_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java依賴倒轉(zhuǎn)原則的定義及問(wèn)題由來(lái)解決方案,感興趣的朋友一起看看吧2017-08-08

