[札记][Java7并发编程实战手册]3.7 并发阶段任务中的阶段切换phaser
[笔记][Java7并发编程实战手册]3.7 并发阶段任务中的阶段切换phaser
[笔记][Java7并发编程实战手册]系列目录
简介
本章主要学习phaser中的阶段切换。在一些场景中,从当前阶段切换到下一阶段过度的时候执行一些操作,那么本章的知识就用上了。
在phaser中,有一个onAdvance方法, 该方法在参与者数量为0的时候,返回true,来表示该phaser状态为终止状态。
下面是默认的处理,还有一个phase参数没有用到,我们可以覆写该方法,通过判断当前阶段来做一些操作,当然得记得上一章中,讲到阶段的几个注意事项。
protected boolean onAdvance(int phase, int registeredParties) {
return registeredParties == 0;
}
本章phaser 使用心得总结
- 继承并覆盖phaser的 onAdvance 方法,来实现阶段切换的功能
- onAdvance方法中的 phase 是阶段的序号,在使用序号来判断的时候,需要注意动态注册的线程的序号会超出预期的阶段序号
示例
游戏闯关示例
场景描述:3个参赛者,参加闯关比赛,但是这个赛制比较奇怪,就是所有参赛者必须等到全部通关,才能开始下一关,官方会在每一个关卡开始前发号命令,报幕闯关开始,闯关结束后,也有谢幕的打印。
/**
* Created by zhuqiang on 2015/8/23 0023.
*/
public class Client {
public static void main(String[] args) throws InterruptedException {
Phaser phaser = new MyPhaser(3);
ArrayList<Thread> list = new ArrayList<Thread>(3);
for (int i = 0; i < 3; i++) {
Thread t = new Thread(new Person(phaser));
list.add(t);
t.start();
}
for (Thread t : list) {
t.join();
}
System.out.println("phaser 是否是终止状态:" + phaser.isTerminated());
}
}
/**自定义 phaser,实现阶段切换的功能*/
class MyPhaser extends Phaser {
public MyPhaser(int parties) {
super(parties);
}
@Override
protected boolean onAdvance(int phase, int registeredParties) {
if (registeredParties == 0) { //参与者为0,当前phaser可以被终止了
System.out.println("《《《官方:本届闯关比赛完美谢幕!");
return true;
} else {
switch (phase){
case 0:
System.out.println("《《《官方:第1关开始·");
return false;
case 1:
System.out.println("《《《官方:第2关开始·");
return false;
case 2:
System.out.println("《《《官方:第3关开始·");
//this.arriveAndDeregister(); //第三关取消注册 注意:不能在 phaser中 调用取消注册的方法,否则抛出 java.lang.IllegalStateException异常,原因是:doArrive(int adjust) 该方法会对unarrived值进校验(好把。源码没有仔细看(看不懂)。所以后面的就不知道为什么会出错了)
return false;
}
}
return super.onAdvance(phase, registeredParties);
}
}
/** 闯关者**/
class Person implements Runnable {
Phaser phaser = null;
public Person(Phaser phaser) {
this.phaser = phaser;
}
@Override
public void run() {
setp(1); //闯第1关
setp(2); //闯第2关
setp(3); //闯第3关
}
/**
* 关卡方法。这里偷点懒,写一个通用方法 来想有几个关卡就传几进来
* @param level 指定是第几关。
*/
public void setp(int level){
phaser.arriveAndAwaitAdvance(); //等待并休眠
long time = (long)(Math.random() * 1000);
try {
TimeUnit.MILLISECONDS.sleep(time); //随机休眠,模拟闯关耗时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf(" %s,闯过了第%s关,耗时:%s\n",Thread.currentThread().getName(),level,time);
if(level == 3){ //第三关是最后一贯,取消线程的注册
phaser.arriveAndDeregister();
}
}
}
某一次的运行结果:
《《《官方:第1关开始·
Thread-0,闯过了第1关,耗时:496
Thread-2,闯过了第1关,耗时:510
Thread-1,闯过了第1关,耗时:799
《《《官方:第2关开始·
Thread-2,闯过了第2关,耗时:804
Thread-0,闯过了第2关,耗时:918
Thread-1,闯过了第2关,耗时:969
《《《官方:第3关开始·
Thread-0,闯过了第3关,耗时:102
Thread-1,闯过了第3关,耗时:534
Thread-2,闯过了第3关,耗时:589
《《《官方:本届闯关比赛完美谢幕!
phaser 是否是终止状态:true
版权声明:本文为博主原创文章,未经博主允许不得转载。