Java multithreading ~~~ Phaser override onAdvance Method
In the Phaser class, after each thread completes a stage, it will wait for other threads to complete and then proceed together.
When a wired thread completes a task, it will call the onAdvance method of Phaser. If we want to complete the order of all threads in each stage
If you do something after work, you have to inherit the Phaser class to override the Onadvance method to achieve our purpose. The following is an example.
The example is to simulate multiple student tests. The test is divided into three stages. After each stage is completed, it will wait for all the students to complete.
In one stage, all the students print a few words after completing a stage task. Let's look at the code below.
Package com. bird. concursey. charpet5; import java. util. date; import java. util. concurrent. phaser; import java. util. concurrent. timeUnit;/*** This class will simulate the students of the exam ** @ author bird September 23, 2014 8:01:47 */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 (), 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 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();default:return true;}}private boolean finishExam() {System.out.printf("Phaser: All the students have finished the exam.\n");System.out.printf("Phaser: Thank you for your time.\n");return false;}private boolean finishSecondExercise() {System.out.printf("Phaser: All the students have 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 have finished the first exercise.\n");System.out.printf("Phaser: It's time for the second one.\n");return false;}/** * It writes two log messages to the console and returns the false value to * indicate that the phaser continues with its execution. * * @return */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;}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);phaser.register();}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();}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());}}
Running result,
Student 0: Has arrived to do the exam.Tue Sep 23 20:11:50 CST 2014Student 3: Has arrived to do the exam.Tue Sep 23 20:11:50 CST 2014Student 2: Has arrived to do the exam.Tue Sep 23 20:11:50 CST 2014Student 4: Has arrived to do the exam.Tue Sep 23 20:11:50 CST 2014Student 1: Has arrived to do the exam.Tue Sep 23 20:11:50 CST 2014Phaser: The exam are going to start. The students are ready.Phaser: We have 5 students.Student 1: Is going to do the first exercise.Tue Sep 23 20:11:50 CST 2014Student 3: Is going to do the first exercise.Tue Sep 23 20:11:50 CST 2014Student 2: Is going to do the first exercise.Tue Sep 23 20:11:50 CST 2014Student 4: Is going to do the first exercise.Tue Sep 23 20:11:50 CST 2014Student 0: Is going to do the first exercise.Tue Sep 23 20:11:50 CST 2014Student 4: Has done the first exercise.Tue Sep 23 20:11:52 CST 2014Student 0: Has done the first exercise.Tue Sep 23 20:11:52 CST 2014Student 1: Has done the first exercise.Tue Sep 23 20:11:52 CST 2014Student 2: Has done the first exercise.Tue Sep 23 20:11:59 CST 2014
This exercise simulates the realization of an exam that has three exercises. All
Students have to finish one exercise before they can start the next one. To implement this
Synchronization requirement, we use the Phaser class, but you have implemented your own
Phaser extending the original class to override the onAdvance () method.
This method is 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
Es as parameters the number of the actual phase, where 0 is the number of the first
Phase and the number of registered maid. The most useful parameter is the actual
Phase. If you execute a different operation depending on the actual phase, you have to use
Alternative structure (if/else or switch) to select the operation you want to execute. In
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 has
Terminated or not. If the phaser returns a false value, it indicates that it hasn't terminated,
So the threads will continue with the execution of other phases. If the phaser returns a true
Value, then the phaser still wakes up the pending threads, but moves the phaser to
Terminated state, so all the future callto any method of the phaser will return immediately,
And the isTerminated () method returns the true value.
In the Core class, when you created the MyPhaser object, you didn't specify the number
Particle in the phaser. You made a call to the register () method for every Student
Object created to register a participating ipant in the phaser. This calling doesn't establish a relation
Between the Student object or the thread that executes it and the phaser. Really,
Number of participants in a phaser is only a number. There is no relationship between
Phaser and the specified object.