Java并发编程 - Phaser类的使用( 四 )

输出结果:
main: 主线程开始执行异步任务 , registeredParties=0, phase=0, isTerminated=falsemain: 注册一个屏障 , registeredParties=2, phase=0, isTerminated=falsemain: 注册一个屏障 , registeredParties=3, phase=0, isTerminated=falsemain: 注册一个屏障 , registeredParties=4, phase=0, isTerminated=falsemain: 注册一个屏障 , registeredParties=5, phase=0, isTerminated=falsemain: 注册一个屏障 , registeredParties=6, phase=0, isTerminated=falsemain: 主线程执行完毕 , registeredParties=5, phase=0, isTerminated=falsethread-0: 到达屏障 , 等待其他线程 , 0, registeredParties=4, phase=0, isTerminated=falsethread-1: 到达屏障 , 等待其他线程 , 1, registeredParties=5, phase=0, isTerminated=falsethread-2: 到达屏障 , 等待其他线程 , 2, registeredParties=5, phase=0, isTerminated=falsethread-3: 到达屏障 , 等待其他线程 , 3, registeredParties=5, phase=0, isTerminated=falsethread-4: 到达屏障 , 等待其他线程 , 4, registeredParties=5, phase=0, isTerminated=falsethread-4: onAdvance , registeredParties=5, phase=0, isTerminated=falsethread-0: 屏障打开 , 开始执行剩下任务 , 0, registeredParties=5, phase=1, isTerminated=falsethread-1: 屏障打开 , 开始执行剩下任务 , 1, registeredParties=4, phase=1, isTerminated=falsethread-2: 屏障打开 , 开始执行剩下任务 , 2, registeredParties=3, phase=1, isTerminated=falsethread-3: 屏障打开 , 开始执行剩下任务 , 3, registeredParties=2, phase=1, isTerminated=falsethread-4: 屏障打开 , 开始执行剩下任务 , 4, registeredParties=1, phase=1, isTerminated=falsethread-4: onAdvance , registeredParties=0, phase=1, isTerminated=false2、例子2(自行控制每个阶段)
Phaser这个类的使用场景为N个线程分阶段并行的问题 。 有这么一个任务为“做3道题“ , 每个学生一个进程 , 5个学生可以并行做 , 这个就是常规的并发 , 但是如果加一个额外的 限制条件 , 必须等所有人都做完了第一题 , 才能开始做第二题 , 必须等所有人都做完了第二题 , 才能做第三题 , 这个问题就转变成了分阶段并发的问题 , 最适合用Phaser来解题 。
private static void test2() {MyPhaser phaser = new MyPhaser();StudentTask[] studentTask = new StudentTask[5];for (int i = 0; i < studentTask.length; i++) {studentTask[i] = new StudentTask(phaser);phaser.register();//注册一次表示phaser维护的线程个数}Thread[] threads = new Thread[studentTask.length];for (int i = 0; i < studentTask.length; i++) {threads[i] = new Thread(studentTask[i], "Student"+i);threads[i].start();}//等待所有线程执行结束for (int i = 0; i < studentTask.length; i++) {try {threads[i].join();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("Phaser has finished:"+phaser.isTerminated());}static class MyPhaser extends Phaser {@Overrideprotected boolean onAdvance(int phase, int registeredParties) { //在每个阶段执行完成后回调的方法switch (phase) {case 0:return studentArrived();case 1:return finishFirstExercise();case 2:return finishSecondExercise();case 3:return finishExam();default:return true;}}private boolean studentArrived(){System.out.println("学生准备好了,学生人数:"+getRegisteredParties());return false;}private boolean finishFirstExercise(){System.out.println("第一题所有学生做完");return false;}private boolean finishSecondExercise(){System.out.println("第二题所有学生做完");return false;}private boolean finishExam(){System.out.println("第三题所有学生做完 , 结束考试");return true;}}static class StudentTask implements Runnable {private Phaser phaser;public StudentTask(Phaser phaser) {this.phaser = phaser;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+" 到达考试");phaser.arriveAndAwaitAdvance();System.out.println(Thread.currentThread().getName()+" 做第1题开始...");doExercise1();System.out.println(Thread.currentThread().getName()+" 做第1题完成...");phaser.arriveAndAwaitAdvance();System.out.println(Thread.currentThread().getName()+" 做第2题开始...");doExercise2();System.out.println(Thread.currentThread().getName()+" 做第2题完成...");phaser.arriveAndAwaitAdvance();System.out.println(Thread.currentThread().getName()+" 做第3题开始...");doExercise3();System.out.println(Thread.currentThread().getName()+" 做第3题完成...");phaser.arriveAndAwaitAdvance();}private void doExercise1() {long duration = (long)(Math.random()*10);try {TimeUnit.SECONDS.sleep(duration);} catch (InterruptedException e) {e.printStackTrace();}}private void doExercise2() {long duration = (long)(Math.random()*10);try {TimeUnit.SECONDS.sleep(duration);} catch (InterruptedException e) {e.printStackTrace();}}private void doExercise3() {long duration = (long)(Math.random()*10);try {TimeUnit.SECONDS.sleep(duration);} catch (InterruptedException e) {e.printStackTrace();}}}输出结果: