这个方法默认实现如下:如果注册的参与者数量为0就返回true,否则就返回false。但是我们可以通过继承Phaser类覆盖这个方法。
package com.packtpub.java7.concurrency.chapter3.recipe6.task; import java.util.concurrent.Phaser; /** * Implements a subclass of the Phaser class. Overrides the onAdvance method to control * the change of phase * */ public class MyPhaser extends Phaser { /** * This method is called when the last register thread calls one of the advance methods * in the actual phase * @param phase Actual phase * @param registeredParties Number of registered threads * @return false to advance the phase, true to finish */ @Override protected boolean onAdvance(int phase, int registeredParties) { switch (phase) { case 0: return studentsArrived(); case 1: return finishFirstExercise(); case 2: return finishSecondExercise(); case 3: return finishExam(); default: return true; } } /** * This method is called in the change from phase 0 to phase 1 * @return false to continue with the execution */ private boolean studentsArrived() { System.out.printf("Phaser: The exam are going to start. The students are ready.\n"); System.out.printf("Phaser: We have %d students.\n",getRegisteredParties()); return false; } /** * This method is called in the change from phase 1 to phase 2 * @return false to continue with the execution */ private boolean finishFirstExercise() { System.out.printf("Phaser: All the students has finished the first exercise.\n"); System.out.printf("Phaser: It's turn for the second one.\n"); return false; } /** * This method is called in the change form phase 2 to phase 3 * @return false to continue with the execution */ private boolean finishSecondExercise() { System.out.printf("Phaser: All the students has finished the second exercise.\n"); System.out.printf("Phaser: It's turn for the third one.\n"); return false; } /** * This method is called in the change from phase 3 to phase 4 * @return true. There are no more phases */ private boolean finishExam() { System.out.printf("Phaser: All the students has finished the exam.\n"); System.out.printf("Phaser: Thank you for your time.\n"); return true; } }
package com.packtpub.java7.concurrency.chapter3.recipe6.task; import java.util.Date; import java.util.concurrent.Phaser; import java.util.concurrent.TimeUnit; /** * This class implements an student in the exam * */ public class Student implements Runnable { /** * Phaser to control the execution */ private Phaser phaser; /** * Constructor of the class. Initialize its objects * @param phaser Phaser to control the execution */ public Student(Phaser phaser) { this.phaser=phaser; } /** * Main method of the student. It arrives to the exam and does three exercises. After each * exercise, it calls the phaser to wait that all the students finishes the same exercise */ public void run() { System.out.printf("%s: Has arrived to do the exam. %s\n",Thread.currentThread().getName(),new Date()); phaser.arriveAndAwaitAdvance(); System.out.printf("%s: Is going to do the first exercise. %s\n",Thread.currentThread().getName(),new Date()); doExercise1(); System.out.printf("%s: Has done the first exercise. %s\n",Thread.currentThread().getName(),new Date()); phaser.arriveAndAwaitAdvance(); System.out.printf("%s: Is going to do the second exercise. %s\n",Thread.currentThread().getName(),new Date()); doExercise2(); System.out.printf("%s: Has done the second exercise. %s\n",Thread.currentThread().getName(),new Date()); phaser.arriveAndAwaitAdvance(); System.out.printf("%s: Is going to do the third exercise. %s\n",Thread.currentThread().getName(),new Date()); doExercise3(); System.out.printf("%s: Has finished the exam. %s\n",Thread.currentThread().getName(),new Date()); phaser.arriveAndAwaitAdvance(); } /** * Does an exercise is to wait a random time */ private void doExercise1() { try { Long duration=(long)(Math.random()*10); TimeUnit.SECONDS.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } } /** * Does an exercise is wait a random time */ private void doExercise2() { try { Long duration=(long)(Math.random()*10); TimeUnit.SECONDS.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } } /** * Does an exercise is wait a random time */ private void doExercise3() { try { Long duration=(long)(Math.random()*10); TimeUnit.SECONDS.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } } }
package com.packtpub.java7.concurrency.chapter3.recipe6.core; import com.packtpub.java7.concurrency.chapter3.recipe6.task.MyPhaser; import com.packtpub.java7.concurrency.chapter3.recipe6.task.Student; /** * Main class of the example * */ public class Main { /** * Main method of the example * @param args */ public static void main(String[] args) { // Creates the Phaser MyPhaser phaser=new MyPhaser(); // Creates 5 students and register them in the phaser Student students[]=new Student[5]; for (int i=0; i<students.length; i++){ students[i]=new Student(phaser); phaser.register(); } // Create 5 threads for the students and start them Thread threads[]=new Thread[students.length]; for (int i=0; i<students.length; i++) { threads[i]=new Thread(students[i],"Student "+i); threads[i].start(); } // Wait for the finalization of the threads for (int i=0; i<threads.length; i++) { try { threads[i].join(); } catch (InterruptedException e) { e.printStackTrace(); } } // Check that the Phaser is in the Terminated state System.out.printf("Main: The phaser has finished: %s.\n",phaser.isTerminated()); } }
工作原理
这个范例模拟了有三道试题的考试过程。所有的学生必须昨晚第一道题才可以开始做第二题。为了实现同步,我们使用了Phaser类,并且通过继承Phaser类和覆盖onAdvance()方法,实现自己的Phaser。
控制台运行结果
Student 0: Has arrived to do the exam. Wed Apr 30 09:53:13 CST 2014
Student 1: Has arrived to do the exam. Wed Apr 30 09:53:13 CST 2014
Student 2: Has arrived to do the exam. Wed Apr 30 09:53:13 CST 2014
Student 4: Has arrived to do the exam. Wed Apr 30 09:53:13 CST 2014
Student 3: Has arrived to do the exam. Wed Apr 30 09:53:13 CST 2014
Phaser: The exam are going to start. The students are ready.
Phaser: We have 5 students.
Student 3: Is going to do the first exercise. Wed Apr 30 09:53:13 CST 2014
Student 4: Is going to do the first exercise. Wed Apr 30 09:53:13 CST 2014
Student 2: Is going to do the first exercise. Wed Apr 30 09:53:13 CST 2014
Student 1: Is going to do the first exercise. Wed Apr 30 09:53:13 CST 2014
Student 0: Is going to do the first exercise. Wed Apr 30 09:53:13 CST 2014
Student 3: Has done the first exercise. Wed Apr 30 09:53:16 CST 2014
Student 0: Has done the first exercise. Wed Apr 30 09:53:19 CST 2014
Student 2: Has done the first exercise. Wed Apr 30 09:53:20 CST 2014
Student 1: Has done the first exercise. Wed Apr 30 09:53:20 CST 2014
Student 4: Has done the first exercise. Wed Apr 30 09:53:21 CST 2014
Phaser: All the students has finished the first exercise.
Phaser: It's turn for the second one.
Student 4: Is going to do the second exercise. Wed Apr 30 09:53:21 CST 2014
Student 0: Is going to do the second exercise. Wed Apr 30 09:53:21 CST 2014
Student 3: Is going to do the second exercise. Wed Apr 30 09:53:21 CST 2014
Student 1: Is going to do the second exercise. Wed Apr 30 09:53:21 CST 2014
Student 2: Is going to do the second exercise. Wed Apr 30 09:53:21 CST 2014
Student 0: Has done the second exercise. Wed Apr 30 09:53:22 CST 2014
Student 4: Has done the second exercise. Wed Apr 30 09:53:22 CST 2014
Student 3: Has done the second exercise. Wed Apr 30 09:53:26 CST 2014
Student 2: Has done the second exercise. Wed Apr 30 09:53:26 CST 2014
Student 1: Has done the second exercise. Wed Apr 30 09:53:26 CST 2014
Phaser: All the students has finished the second exercise.
Phaser: It's turn for the third one.
Student 1: Is going to do the third exercise. Wed Apr 30 09:53:26 CST 2014
Student 0: Is going to do the third exercise. Wed Apr 30 09:53:26 CST 2014
Student 3: Is going to do the third exercise. Wed Apr 30 09:53:26 CST 2014
Student 2: Is going to do the third exercise. Wed Apr 30 09:53:26 CST 2014
Student 2: Has finished the exam. Wed Apr 30 09:53:26 CST 2014
Student 4: Is going to do the third exercise. Wed Apr 30 09:53:26 CST 2014
Student 4: Has finished the exam. Wed Apr 30 09:53:32 CST 2014
Student 1: Has finished the exam. Wed Apr 30 09:53:32 CST 2014
Student 0: Has finished the exam. Wed Apr 30 09:53:34 CST 2014
Student 3: Has finished the exam. Wed Apr 30 09:53:34 CST 2014
Phaser: All the students has finished the exam.
Phaser: Thank you for your time.
Main: The phaser has finished: true.