背景
某一天,小明跟五个嫂子玩游戏(羡煞我也),游戏共三关,这个游戏小明都是轻车熟路,每次都是第一个完成,但是为了照顾几个嫂子,体现一下绅士风度,得等嫂子们都完成才能继续下一关的探索啊。那怎么办呢,小明绞尽脑汁,想到了CountDownLatch和CyclicBarrier来解决这个问题。
但是过了一会发现这两个不太好使,这该怎么办呢,这种关键时刻可不能掉链子,于是想啊想,查啊查,终于发现了JUC下还有一样宝贝能解决这个问题,还比之前那两个灵活好用。它就是Phaser。
于是乎,小明就开始探索了起来。
要求
- 小明和5个嫂子玩游戏。
- 游戏共三关。
- 为体现绅士风度,必须等所有人都完成这一关,才能开始下一关的探索。
- 三关都完成后,游戏结束,嫂子们为小明发好人卡。
package com.ywu.demo.normal.juc;
import java.util.concurrent.Phaser;
/**
* @description juc phaser测试类
* 1. 小明和5个嫂子玩游戏。
* 2. 游戏共三关。
* 3. 为体现绅士风度,必须等所有人都完成这一关,才能开始下一关的探索。
* 4. 三关都完成后,游戏结束,嫂子为小明发好人卡。
* @author ywu
* @date 2019/12/3
*/
public class PhaseTest {
public static void main(String[] args) {
Phaser phaser = new MyPhase();
for (int i = 0; i < 6; i++) {
Thread thread = new Thread(() -> {
// 调用该方法表示 到达某一阶段 并等待其他线程到达
System.out.println(Thread.currentThread().getName() + "开始准备...");
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + "开始第一关...");
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + "开始第二关...");
phaser.arriveAndAwaitAdvance();
System.out.println(Thread.currentThread().getName() + "开始第三关...");
phaser.arriveAndAwaitAdvance();
});
thread.setName("玩家" + (i + 1));
// 注册线程个数
phaser.register();
thread.start();
}
}
}
class MyPhase extends Phaser {
/**
* 重写该方法 实现自定义逻辑
* @param phase 阶段
* @param registeredParties 到达的线程数
* @return
*/
@Override
protected boolean onAdvance(int phase, int registeredParties) {
// 每到达一个阶段 都会触发当前方法 每一个阶段phase都会加1 从0开始
// 返回值 true 表示结束所有几段, false表示继续
switch (phase) {
case 0:
// 游戏准备阶段
prepareStage();
return false;
case 1:
// 第一关
firstStage();
return false;
case 2:
// 第二关
secondStage();
return false;
case 3:
// 第三关 完成 结束比赛
thirdStage();
return true;
default:
return true;
}
}
void prepareStage() {
System.out.println("所有人已准备完成,游戏准备开始,参加游戏人数:" + getRegisteredParties());
}
void firstStage() {
System.out.println("所有人已完成第一关,即将开始第二关,已就位人数:" + getRegisteredParties());
}
void secondStage() {
System.out.println("所有人已完成第二关,即将开始第三关,已就位人数:" + getRegisteredParties());
}
void thirdStage() {
System.out.println("所有人已完成第三关,游戏结束,完成人数:" + getRegisteredParties());
System.out.println("此次游戏圆满结束,嫂子们一人发给小明一张好人卡...");
}
}
游戏结果
玩家1开始准备...
玩家2开始准备...
玩家5开始准备...
玩家6开始准备...
玩家4开始准备...
玩家3开始准备...
所有人已准备完成,游戏准备开始,参加游戏人数:6
玩家3开始第一关...
玩家5开始第一关...
玩家1开始第一关...
玩家6开始第一关...
玩家4开始第一关...
玩家2开始第一关...
所有人已完成第一关,即将开始第二关,已就位人数:6
玩家2开始第二关...
玩家5开始第二关...
玩家3开始第二关...
玩家1开始第二关...
玩家6开始第二关...
玩家4开始第二关...
所有人已完成第二关,即将开始第三关,已就位人数:6
玩家4开始第三关...
玩家5开始第三关...
玩家1开始第三关...
玩家3开始第三关...
玩家6开始第三关...
玩家2开始第三关...
所有人已完成第三关,游戏结束,完成人数:6
此次游戏圆满结束,嫂子们一人发给小明一张好人卡...
游戏结束后,小明开开心心的拿着好人卡回去。