Phaser, introduced by Java7, is a new use of the Sync tool in Java SE 7, which overlaps with cyclicbarrier and countdownlatch on features, but it provides a more flexible and powerful usage.
Cyclicbarrier, which allows a group of threads to wait for each other until a common barrier point is reached. It provides an await () that enables all participants to wait until the critical point arrives.
Countdownlatch, it allows one or more threads to wait until a set of operations that are being performed in another thread is completed. It provides an await (), Countdown () two methods to operate.
In Phaser, it divides the tasks performed by multiple threads into multiple phases, which require explicit tasks at each stage, each of which can have any participant, and threads can register and participate in a phase at any time.
Structure
After Phaser is created, the initial stage number is 0, and the initial number of participants is specified in the constructor.
Registration: Registration
Phaser supports dynamically adjusting the number of registration tasks through the Register () and bulkregister (int parties) methods.
Arrival
Each phaser instance maintains a phase number with an initial value of 0. Whenever all registered tasks arrive at Phaser, phase number accumulates and is zeroed out after Integer.max_value. The arrive () and Arriveandderegister () methods are used to record arrival, where arrive (), a participant is called after the task is completed, Arriveandderegister (), the task is completed, and the registration is canceled. Arriveandawaitadvance (), completes its own waiting for other participants to complete and enters the block until Phaser successfully enters the next stage.
Example 1
public class Phasertest_1 {public static void Main (string[] args) { Phaser Phaser = new Phaser (5); for (int i = 0; i < 5; i++) { task_01 task_01 = new task_01 (phaser); Thread thread = new Thread (task_01, "phasetest_" + i); Thread.Start (); } } Static class Task_01 implements runnable{ private final Phaser Phaser; Public task_01 (Phaser Phaser) { this.phaser = Phaser; } @Override public Void Run () { System.out.println (Thread.CurrentThread (). GetName () + "performs the task, waits for other tasks to execute ......"); Wait for other tasks to complete phaser.arriveandawaitadvance (); System.out.println (Thread.CurrentThread (). GetName () + "Resume task ...");}}
Operation Result:
Phasetest_0 perform tasks, wait for other tasks to execute ... Phasetest_1 perform tasks, wait for other tasks to execute ... Phasetest_3 perform tasks, wait for other tasks to execute ... Phasetest_2 perform tasks, wait for other tasks to execute ... Phasetest_4 perform tasks, wait for other tasks to execute ... Phasetest_4 continue to perform the task ... Phasetest_1 continue to perform the task ... Phasetest_0 continue to perform the task ... Phasetest_2 continue to perform the task ... Phasetest_3 continue to perform the task ...
In this instance we can confirm that all child threads ****+ "continue to perform tasks ..." are executed after the thread calls the Arriveandawaitadvance () method.
Example 2
As mentioned earlier, Phaser provides more powerful and flexible functions than Countdownlatch, Cyclicbarrier, and in a way, Phaser can replace them:
public class Phasertest_5 {public static void main (string[] args) {Phaser Phaser = new Phaser (1); Equivalent to Countdownlatch (1)//five subtasks for (int i = 0; i < 3; i++) {task_05 task = new Task_ (phaser); Thread thread = new Thread (task, "phasetest_" + i); Thread.Start (); } try {//wait 3 seconds Thread.Sleep (3000); } catch (Interruptedexception e) {e.printstacktrace (); } phaser.arrive (); Countdownlatch.countdown ()} Static class Task_05 implements runnable{private final Phaser Phaser; Task_05 (Phaser Phaser) {this.phaser = Phaser; } @Override public void Run () {phaser.awaitadvance (Phaser.getphase ()); Countdownlatch.await () System.out.println (Thread.CurrentThread (). GetName () + "Perform tasks ..."); } }}
Here, the task does not actually execute at first, but waits three seconds to execute.
For Cyclicbarrier It is much simpler to replace the direct arriveandawaitadvance () method, such as Example 1.
Example 3
In Cyclicbarrier, you can execute an action after the task has finished executing, and there is a corresponding action in phaser, but Phaser need to override the Onadvance () method:
public class Phasertest_3 {public static void main (string[] args) {Phaser Phaser = new Phaser (3) {/ * * registeredparties: Number of thread registrations * phase: Number of threads entering the method, */protected Boolean OnA dvance (int phase, int registeredparties) {System.out.println ("execute Onadvance method ...; Phase: "+ phase +" registeredparties= "+ registeredparties); return phase = = 3; } }; for (int i = 0; i < 3; i++) {task_03 Task = new task_03 (phaser); Thread thread = new Thread (task, "task_" + i); Thread.Start (); } while (!phaser.isterminated ()) {phaser.arriveandawaitadvance (); The main thread waits for} System.out.println ("The main thread task has ended ...."); } Static class Task_03 implements runnable{private final Phaser Phaser; Public task_03 (Phaser Phaser) {this.phaser = Phaser; } @Override public void Run () {do{try {thread.sleep (500); } catch (Interruptedexception e) {e.printstacktrace (); } System.out.println (Thread.CurrentThread (). GetName () + "start task ..."); Phaser.arriveandawaitadvance (); }while (!phaser.isterminated ()); } }}
Operation Result:
Task_0 start to perform the task ... task_1 start the task ... Task_1 execute onadvance method ...; Phase:0registeredparties=3task_2 Start the task ... task_0 start the task ... task_1 start the task ... task_0 execute onadvance method ...; Phase:1registeredparties=3task_2 Start the task ... task_2 execute the Onadvance method ...; Phase:2registeredparties=3 main thread task has ended .... task_0 start to perform the task ...
Reference blog:
1. What's New on Java 7 Phaser
2, http://blog.csdn.net/andycpp/article/details/8838820
Java concurrency Programming Combat-"J.U.C": Phaser