In the Phaser class, we will wait for the other threads to finish after each thread completes a phase in each of the threads, and then
When a thread completes a task, it calls Phaser's Onadvance method, and if we want to do it at each stage, all threads complete their order
Do something after work, then you have to inherit the Phaser class to rewrite onadvance this method to achieve our goal, let us use an example
Ming, the example is to simulate a number of student exams, the exam is divided into three stages, each stage is completed, will wait for all students to complete, and we hope that in every
A stage where all the students complete a phase of the task after printing out a few words, see the code below.
Package Com.bird.concursey.charpet5;import Java.util.date;import Java.util.concurrent.phaser;import java.util.concurrent.timeunit;/** * This class would simulate the students of the exam * * @author Bird September 23, 2014 8:01: */public class Student implements Runnable {private Phaser phaser;public Student (Phaser Phaser) {super (); This.phaser = Phaser;} @Overridepublic void Run () {System.out.printf ("%s:has arrived to do the exam.%s\n", Thread.CurrentThread (). GetName (), NE W Date ());p haser.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 ());p haser.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 done the third exercise.%s\n", Thread.CurrentThread (). GetName (), New Date ()); Phaser.arriveandawaitadvance ();} private void DoExercise3 () {try {long duration = (long) (Math.random () * 10); TimeUnit.SECONDS.sleep (duration);} catch (Interruptedexception e) {e.printstacktrace ();}} private void DoExercise2 () {try {long duration = (long) (Math.random () * 10); TimeUnit.SECONDS.sleep (duration);} catch (Interruptedexception e) {e.printstacktrace ();}} private void DoExercise1 () {try {long duration = (long) (Math.random () * 10); TimeUnit.SECONDS.sleep (duration);} catch (Interruptedexception e) {e.printstacktrace ();}}}
Package Com.bird.concursey.charpet5;import Java.util.concurrent.phaser;public Class Myphaser extends Phaser {@ overrideprotected boolean onadvance (int phase, int registeredparties) {switch (phase) {case 0:return studentsarrived (); Case 1:return Finishfirstexercise (), Case 2:return finishsecondexercise (), Case 3:return Finishexam ();d Efault:return true;}} Private Boolean Finishexam () {System.out.printf ("Phaser:all The students has finished the exam.\n"); System.out.printf ("Phaser:thank for Your time.\n"); return false;} Private Boolean finishsecondexercise () {System.out.printf ("Phaser:all The students has finished the second exercise.\n" ); System.out.printf ("Phaser:it ' s time for the third one.\n"); return false;} Private Boolean finishfirstexercise () {System.out.printf ("Phaser:all The students has finished the first exercise.\n"); System.out.printf ("Phaser:it ' s time for the second one.\n"); return false;} /** * It writes-log messages to the console and returns the False value to * INDIcate The Phaser continues with its execution. * * @return */private boolean studentsarrived () {System.out.printf ("phaser:the exam is going to start. The students is ready.\n "); System.out.printf ("Phaser:we has%d students.\n", getregisteredparties ()); return false;} public static void Main (string[] args) {Myphaser phaser = new Myphaser (); Student students[] = new Student[5];for (int i = 0; i < students.length; i++) {students[i] = new Student (Phaser);p Haser . Register (); Thread threads[] = new Thread[students.length];for (int i = 0; i < students.length; i++) {threads[i] = new Thread (stude Nts[i], "Student" + i); Threads[i].start ();} for (int i = 0; i < threads.length; i++) {try {threads[i].join ();} catch (Interruptedexception e) {e.printstacktrace (); }}system.out.printf ("Main:the Phaser has finished:%s.\n", phaser.isterminated ());}}
Run the results,
Student 0:has arrived to do the exam. Tue Sep 20:11:50 CST 2014Student 3:has arrived to do the exam. Tue Sep 20:11:50 CST 2014Student 2:has arrived to do the exam. Tue Sep 20:11:50 CST 2014Student 4:has arrived to do the exam. Tue Sep 20:11:50 CST 2014Student 1:has arrived to do the exam. Tue Sep 20:11:50 CST 2014phaser:the exam is going to start. The students is ready. Phaser:we has 5 students. Student 1:is going to do the first exercise. Tue Sep 20:11:50 CST 2014Student 3:is going to do the first exercise. Tue Sep 20:11:50 CST 2014Student 2:is going to do the first exercise. Tue Sep 20:11:50 CST 2014Student 4:is going to do the first exercise. Tue Sep 20:11:50 CST 2014Student 0:is going to do the first exercise. Tue Sep 20:11:50 CST 2014Student 4:has done the first exercise. Tue Sep 20:11:52 CST 2014Student 0:has done the first exercise. Tue Sep 20:11:52 CST 2014Student 1:has done the first exercise. Tue Sep 20:11:52 CST 2014Student 2:has doNE the first exercise. Tue Sep 20:11:59 CST 2014
This exercise simulates the realization of a exam that have three exercises. All the
Students has to finish one exercise before they can start the next one. To implement this
Synchronization requirement, we use the Phaser class, and you have implemented your own
Phaser extending the original class to override the Onadvance () method.
This method was called by the Phaser before making a phase change and before waking up all
The threads that were sleeping in the Arriveandawaitadvance () method. This method
Receives as parameters the number of the actual phase, where 0 is the number of the first
Phase and the number of registered participants. The most useful parameter is the actual
Phase. If you execute a different operation depending in the actual phase, you
Alternative structure (if/else or switch) to select the operation your want to execute. In the
example, we used a switch structure to select a different method for each change of phase.
The Onadvance () method returns a Boolean value that indicates if the phaser have
Ter Minated or not. If the Phaser returns a false value, it indicates it hasn ' t terminated,
So the threads would continue with the exec Ution of other phases. If The Phaser returns a true
value, then the phaser still wakes up the pending threads, but moves the phaser to the
Terminated state, so all the calls to any method of the Phaser would return immediately,
and the isterminated () m Ethod returns the true value.
In the Core class, when you created the Myphaser object, you didn ' t specify the number of
Participants in the Phaser. You made a call to the register () method for every Student
Object created to register a participant in the Phaser. This calling doesn ' t establish a relation
Between the Student object or the thread that executes it and the Phaser. Really, the
Number of participants in a phaser are only a number. There is no relationship between the
Phaser and the participants.
Java multi-thread ~~~phaser overriding Onadvance method