Open In App

Java.util.concurrent.Phaser class in Java with Examples

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: 



public Phaser()
public Phaser(int parties)
throws IllegalArgumentException
public Phaser(Phaser parent)
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");
        }
    }
}

Output
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");
        }
    }
}

Output
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: 

public int register()
throws IllegalArgumentException
public int arrive()
throws IllegalStateException
public int arriveAndDeregister()
throws IllegalStateException
public int arriveAndAwaitAdvance()
throws IllegalStateException
public final int getPhase() 
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");
    }
}

Output
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
 


Article Tags :