Phaser’s primary purpose is to enable synchronization of threads that represent one or more phases of activity. It lets us define a synchronization object that waits until a specific phase has been completed. It then advances to the next phase until that phase concludes. It can also be used to synchronize a single phase, and in that regard, it acts much like a CyclicBarrier.
Class Hierarchy
java.lang.Object ? java.util.concurrent ? Class Phaser
Syntax
public class Phaser extends Object
Constructors:
- Phaser() – This creates a phaser with initially zero registered parties. A thread can only use this phaser after registering for it.
public Phaser()
- Phaser(int parties) – This creates a phaser that requires parties number of threads to advance to the next phase.
public Phaser(int parties) throws IllegalArgumentException
- Phaser(Phaser parent) – This specifies a parent phaser for the new object. The number of registered parties is set to zero.
public Phaser(Phaser parent)
- Phaser(Phaser parent, int parties) – This specifies a parent phaser for the newly created object and the number of parties required to advance to the next phase.
public Phaser(Phaser parent, int parties) throws IllegalArgumentException
Example1:
Note: Output may vary with each run.
// Java program to show Phaser Class import java.util.concurrent.Phaser;
// A thread of execution that uses a phaser. class MyThread implements Runnable {
Phaser phaser;
String title;
public MyThread(Phaser phaser, String title)
{
this .phaser = phaser;
this .title = title;
phaser.register();
new Thread( this ).start();
}
@Override public void run()
{
System.out.println( "Thread: " + title
+ " Phase Zero Started" );
phaser.arriveAndAwaitAdvance();
// Stop execution to prevent jumbled output
try {
Thread.sleep( 10 );
}
catch (InterruptedException e) {
System.out.println(e);
}
System.out.println( "Thread: " + title
+ " Phase One Started" );
phaser.arriveAndAwaitAdvance();
// Stop execution to prevent jumbled output
try {
Thread.sleep( 10 );
}
catch (InterruptedException e) {
System.out.println(e);
}
System.out.println( "Thread: " + title
+ " Phase Two Started" );
phaser.arriveAndDeregister();
}
} public class PhaserExample {
public static void main(String[] args)
{
Phaser phaser = new Phaser();
phaser.register();
int currentPhase;
System.out.println( "Starting" );
new MyThread(phaser, "A" );
new MyThread(phaser, "B" );
new MyThread(phaser, "C" );
// Wait for all threads to complete phase Zero.
currentPhase = phaser.getPhase();
phaser.arriveAndAwaitAdvance();
System.out.println( "Phase " + currentPhase
+ " Complete" );
System.out.println( "Phase Zero Ended" );
// Wait for all threads to complete phase One.
currentPhase = phaser.getPhase();
phaser.arriveAndAwaitAdvance();
System.out.println( "Phase " + currentPhase
+ " Complete" );
System.out.println( "Phase One Ended" );
currentPhase = phaser.getPhase();
phaser.arriveAndAwaitAdvance();
System.out.println( "Phase " + currentPhase
+ " Complete" );
System.out.println( "Phase Two Ended" );
// Deregister the main thread.
phaser.arriveAndDeregister();
if (phaser.isTerminated()) {
System.out.println( "Phaser is terminated" );
}
}
} |
Starting Thread: B Phase Zero Started Thread: A Phase Zero Started Thread: C Phase Zero Started Thread: A Phase One Started Thread: B Phase One Started Thread: C Phase One Started Phase 0 Complete Phase Zero Ended Phase 1 Complete Phase One Ended Thread: C Phase Two Started Thread: A Phase Two Started Thread: B Phase Two Started Phase 2 Complete Phase Two Ended Phaser is terminated
Example2:
// Java program to show Phaser Class import java.util.concurrent.Phaser;
// A thread of execution that uses a phaser. class MyThread implements Runnable {
Phaser phaser;
String title;
public MyThread(Phaser phaser, String title)
{
this .phaser = phaser;
this .title = title;
phaser.register();
new Thread( this ).start();
}
@Override public void run()
{
System.out.println( "Thread: " + title
+ " Phase Zero Started" );
phaser.arriveAndAwaitAdvance();
// Stop execution to prevent jumbled output
try {
Thread.sleep( 10 );
}
catch (InterruptedException e) {
System.out.println(e);
}
System.out.println( "Thread: " + title
+ " Phase One Started" );
phaser.arriveAndAwaitAdvance();
// Stop execution to prevent jumbled output
try {
Thread.sleep( 10 );
}
catch (InterruptedException e) {
System.out.println(e);
}
System.out.println( "Thread: " + title
+ " Phase Two Started" );
phaser.arriveAndDeregister();
}
} public class PhaserExample {
public static void main(String[] args)
{
Phaser phaser = new Phaser();
phaser.register();
int currentPhase;
System.out.println( "Starting" );
new MyThread(phaser, "A" );
new MyThread(phaser, "B" );
new MyThread(phaser, "C" );
// Wait for all threads to complete phase Zero.
currentPhase = phaser.getPhase();
phaser.arriveAndAwaitAdvance();
System.out.println( "Phase " + currentPhase
+ " Complete" );
System.out.println( "Phase Zero Ended" );
// Wait for all threads to complete phase One.
currentPhase = phaser.getPhase();
phaser.arriveAndAwaitAdvance();
System.out.println( "Phase " + currentPhase
+ " Complete" );
System.out.println( "Phase One Ended" );
currentPhase = phaser.getPhase();
phaser.arriveAndAwaitAdvance();
System.out.println( "Phase " + currentPhase
+ " Complete" );
System.out.println( "Phase Two Ended" );
// Deregister the main thread.
phaser.arriveAndDeregister();
if (phaser.isTerminated()) {
System.out.println( "Phaser is terminated" );
}
}
} |
Starting Thread: C Phase Zero Started Thread: A Phase Zero Started Thread: B Phase Zero Started Thread: B Phase One Started Thread: C Phase One Started Thread: A Phase One Started Phase 0 Complete Phase Zero Ended Phase 1 Complete Phase One Ended Thread: A Phase Two Started Thread: C Phase Two Started Thread: B Phase Two Started Phase 2 Complete Phase Two Ended Phaser is terminated
Methods:
- int register() – This method is used to register parties after a phaser has been constructed. It returns the phase number of the phase to which it is registered.
public int register() throws IllegalArgumentException
- int arrive() – This method signals that a thread has completed some portion of the task. It does not suspend the execution of the calling thread. It returns the current phase number or a negative value if the phaser has been terminated.
public int arrive() throws IllegalStateException
- int arriveAndDeregister() – This method enables a thread to arrive at a phase and deregister itself, without waiting for other threads to arrive. It returns the current phase number or a negative value if the phaser has been terminated.
public int arriveAndDeregister() throws IllegalStateException
- int arriveAndAwaitAdvance() – This method suspends the execution of the thread at a phase, to wait for other threads. It returns the current phase number or a negative value if the phaser has been terminated.
public int arriveAndAwaitAdvance() throws IllegalStateException
- final int getPhase() – This method returns the current phase number. A negative value is returned if the invoking phasers terminated.
public final int getPhase()
- boolean onAdvance(int phase, int parties) – This method helps in defining how a phase advancement should occur. To do this, the user must override this method. To terminate the phaser, onAdvance() method returns true, otherwise, it returns false;
protected boolean onAdvance(int phase, int parties)
Example to demonstrate the methods of Phaser class – where the method is overridden so that the phaser executes only a specified number of phases.
// Java program to demonstrate // the methods of Phaser class import java.util.concurrent.Phaser;
// Extend MyPhaser and override onAdvance() // so that only specific number of phases // are executed class MyPhaser extends Phaser {
int numPhases;
MyPhaser( int parties, int phaseCount)
{
super (parties);
numPhases = phaseCount - 1 ;
}
@Override
protected boolean onAdvance( int phase,
int registeredParties)
{
System.out.println( "Phase " + phase
+ " completed.\n" );
// If all phases have completed, return true.
if (phase == numPhases || registeredParties == 0 ) {
return true ;
}
// otherwise, return false
return false ;
}
} // A thread of execution that uses a phaser class ModifiedThread implements Runnable {
Phaser phsr;
String name;
ModifiedThread(Phaser p, String n)
{
phsr = p;
name = n;
phsr.register();
new Thread( this ).start();
}
@Override public void run()
{
while (!phsr.isTerminated()) {
System.out.println( "Thread " + name
+ " Beginning Phase "
+ phsr.getPhase());
phsr.arriveAndAwaitAdvance();
try {
Thread.sleep( 10 );
}
catch (InterruptedException e) {
System.out.println(e);
}
}
}
} public class PhaserExample2 {
public static void main(String[] args)
{
MyPhaser phsr = new MyPhaser( 1 , 4 );
System.out.println( "Starting" );
new ModifiedThread(phsr, "A" );
new ModifiedThread(phsr, "B" );
new ModifiedThread(phsr, "C" );
while (!phsr.isTerminated()) {
phsr.arriveAndAwaitAdvance();
}
System.out.println( "The phaser is terminated\n" );
}
} |
Starting Thread B Beginning Phase 0 Thread C Beginning Phase 0 Thread A Beginning Phase 0 Phase 0 completed. Thread A Beginning Phase 1 Thread B Beginning Phase 1 Thread C Beginning Phase 1 Phase 1 completed. Thread C Beginning Phase 2 Thread A Beginning Phase 2 Thread B Beginning Phase 2 Phase 2 completed. Thread A Beginning Phase 3 Thread B Beginning Phase 3 Thread C Beginning Phase 3 Phase 3 completed. The phaser is terminated
Reference: https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Phaser.html