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,并重寫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)用場景
以簡單的結(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 讀取網(wǎng)絡(luò)圖片存儲(chǔ)到本地并生成縮略圖
用Java做開發(fā)經(jīng)常需要處理圖片。本文就來看一下如何保存圖片到本地并生成縮略圖2021-05-05
intelliJ idea 2023 配置Tomcat 8圖文教程
這篇文章主要介紹了intelliJ idea 2023 配置Tomcat 8教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
MyBatis-Plus自定義SQL和復(fù)雜查詢的實(shí)現(xiàn)
MyBatis-Plus增強(qiáng)了MyBatis的功能,提供注解和XML兩種自定義SQL方式,支持復(fù)雜查詢?nèi)缍啾黻P(guān)聯(lián)、動(dòng)態(tài)分頁等,通過注解如@Select、@Insert、@Update、@Delete實(shí)現(xiàn)CRUD操作,本文就來介紹一下,感興趣的可以了解一下2024-10-10
Java servlet執(zhí)行流程代碼實(shí)例
這篇文章主要介紹了Java servlet執(zhí)行流程代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
短網(wǎng)址的原理與生成方法(Java實(shí)現(xiàn))
這篇文章主要給大家介紹了關(guān)于短網(wǎng)址的原理與生成方法,利用的是Java實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
Mybatis-Plus自動(dòng)生成的數(shù)據(jù)庫id過長的解決
這篇文章主要介紹了Mybatis-Plus自動(dòng)生成的數(shù)據(jù)庫id過長的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12

