In CyclicBarrier we used to register parties in constructor but Phaser provides us flexibility of registering and deRegistering parties at any time.

For registering parties, we may use any of the following -

constructors, or

int register(), or

bulkRegister().

For deRegistering parties, we may use any of the following -

arriveAndDeregister()

Phaser’s constructor in java >

Phaser()

Creates a new phaser with no initially registered parties.

Any thread which want to use this phaser must register it first.

Phaser is created without parent.

Initially phase number is 0.

Phaser(int parties)

Creates a new phaser with the parties number of registered unarrived parties.

Phaser is created without parent.

Initially phase number is 0.

Phaser(Phaser parentPhaser, int parties).

Creates a new phaser with the given parent and number of registered unarrived parties.

When the parent is non-null and the parties is greater than 0, this childPhaser is registered with its parent.

parentPhaser does not terminates until childPhaser is not terminated.

/*

*Creates a new phaser (parentPhaser) with no registered unArrived parties

*/

Phaser parentPhaser = new Phaser();

/*

* Creates a new phaser (childPhaser ) with the given parent &

* no registered unArrived parties.

*/

Phaser childPhaser = new Phaser(parentPhaser,0);

Now, parentPhaser does not terminates until childPhaser is not terminated.

In below section i have shown usage of this constructor with program.

Phaser(Phaser parent)

Internally it calls phaser(parent,0).

Phaser methods in java >

int register()

Adds/Registers a new unarrived party to this phaser. It returns >

the arrival phase number to which this registration applied.

If phaser has terminated then value is negative and registration has no effect.

If invocation of onAdvance() method is in progress than before returning this method may await its completion.

If this phaser has a parent, and there were no registered parties with this phaser, this child phaser is also registered with its parent.

int bulkRegister(int parties)

Adds parties number of new unarrived parties to this phaser. It returns >

the arrival phase number to which this registration applied.

If phaser has terminated then value is negative and registration has no effect.

If invocation of onAdvance() method is in progress than before returning this method may await its completion.

If this phaser has a parent, and parties is greater than 0, and there were no registered parties with this phaser, this child phaser is also registered with its parent.

int arriveAndDeregister()

Current thread (Party) Arrives and deRegisters from phaser. DeRegistration reduces the number of parties that may be required in future to move to next phase.

Few small questions might come to your mind.

What do you mean by Adds/Registers a new unarrived party to this phaser ?

When we create instance of MyRunnable, we call phaser.register() in constructor, till that time thread (party) on that instance is not started (i.e. party has not arrived), we have only registered phaser.

int arrive()

Method is called to signal that party (current thread) has completed a phase. It returns >

the arrival phase number.

If phaser has terminated then value is negative.

If any unregistered party calls arrive() than IllegalStateException is thrown,

When does phase completes?

When number of arrivals = number of registered parties.

Does arrive() cause current thread to wait for other registered threads to complete current phase?

No, arrive() method does not cause current thread to wait for other registered threads to complete current phase. That means current thread can immediately start next phase without waiting for any other registered thread to complete current phase.

int arriveAndAwaitAdvance()

Method is called to signal that party (current thread) has completed a phase.

It returns >

the arrival phase number.

If phaser has terminated then value is negative.

If any unregistered party calls arrive() IllegalStateException is thrown,

When does phase completes?

When number of arrivals = number of registered parties.

Now let’s figure out difference between arrive() and arriveAndAwaitAdvance().

Does arriveAndAwaitAdvance() method causes current thread to wait for other registered threads to complete current phase?

Yes, arriveAndAwaitAdvance() method causes current thread to wait for other registered threads to complete current phase. That means current thread can proceed to next phase only when all other threads have completed current phase (i.e. by calling arriveAndAwaitAdvance() method).

int getPhase()

getPhase() method can be used for monitoring purposes. Method returns the current phase number.

For first phase it returns 0, for second phase it returns 1 and so on.

boolean isTerminated()

isTerminated() method returns true if phaser has been terminated.

When is phaser terminated?

when calling arriveAndDeregister() methods has caused the number of registered parties to become 0.

Termination can also be triggered when an onAdvance() method returns true.

boolean onAdvance(int phase, int registeredParties)

We can override the onAdvance( ) method to control number of phases which we want to execute.

phase is the current phase number when we enter onAdvance() method i.e. before advancing to next phase.

registeredParties is the current number of registered parties

Everytime before advancing to next phase overriden onAdvance() method is called and returns either true or false.

If method returns true than phaser isterminated ,or

If method returns false than phaser continues and can advance to next phase.

Few more quick facts about Phaser >

Like a CyclicBarrier, a Phaser can be awaited repeatedly in java.

Maximum number of parties that could be registered with phaser at a time is 65535, if we try to register more parties IllegalStateException will be thrown in java.

Phasers may be constructed in tree structures to reduce contention in java.

/*arriveAndAwaitAdvance() will cause thread to wait until current phase

* has been completed i.e. until all registered threads

* call arriveAndAwaitAdvance()

*/

phaser.arriveAndAwaitAdvance();

System.out.println("------Phase-"+currentPhase+" has been COMPLETED----------");

}

}

}

class MyRunnable implements Runnable{

Phaser phaser;

MyRunnable(Phaser phaser,String name){

this.phaser=phaser;

this.phaser.register(); //Registers/Add a new unArrived party to this phaser.

System.out.println(name+" - New unarrived party has "

+ "been registered with phaser");

}

@Override

publicvoid run() {

while(!phaser.isTerminated()){

System.out.println(Thread.currentThread().getName() +

" - party has arrived and is working in "

+ "Phase-"+phaser.getPhase());

phaser.arriveAndAwaitAdvance();

//Sleep has been used for formatting output

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

/*OUTPUT

new phaser with 1 registered unArrived parties created and initial phase number is 0

first - New unarrived party has been registered with phaser

second - New unarrived party has been registered with phaser

third - New unarrived party has been registered with phaser

--------Phaser has started---------------

Thread-1 - party has arrived and is working in Phase-0

Thread-2 - party has arrived and is working in Phase-0

Thread-3 - party has arrived and is working in Phase-0

onAdvance() method, current phase=0

onAdvance() method, returning false, hence phaser will continue

------Phase-0 has been COMPLETED----------

Thread-2 - party has arrived and is working in Phase-1

Thread-1 - party has arrived and is working in Phase-1

Thread-3 - party has arrived and is working in Phase-1

onAdvance() method, current phase=1

onAdvance() method, returning true, hence phaser will terminate

------Phase-1 has been COMPLETED----------

*/

Let’s discuss output in detail, to get better understanding of how we can override Phaser’s onAdvance method to control number of phase we want to execute in java >

Note: I have mentioned output in green text.

new phaser with 1 registered unArrived parties created and initial phase number is 0

public PhaserOnAdvanceTest(int parties) {

super(parties);

}

Creates a new phaser with 1 registered unArrived parties and initial phase number is 0.

first - New unarrived party has been registered with phaser

second - New unarrived party has been registered with phaser

third - New unarrived party has been registered with phaser

We have created 3 MyRunnable objects and in MyRunnable’s constructor all 3 new unarrived party has been registered with phaser.

--------Phaser has started---------------

main thread has called arriveAndAwaitAdvance() and waiting for other 3 registered parties (Thread-1, Thread-2 and Thread-3) to call arriveAndAwaitAdvance().

Thread-1 - party has arrived and is working in Phase-0

Thread-1 (party) has called arriveAndAwaitAdvance() and waiting for other 2 registered parties to call arriveAndAwaitAdvance()

Thread-2 - party has arrived and is working in Phase-0

Thread-2 (one more party) has called arriveAndAwaitAdvance() and waiting for another 1 registered party to call arriveAndAwaitAdvance()

Thread-3 - party has arrived and is working in Phase-0

Now, all registered parties have called arriveAndAwaitAdvance(), main thread can resume.

onAdvance() method, current phase=0

Everytime before advancing to next phase overridden onAdvance() method is called and returns either true or false.

Hence, we enter onAdvance() method and current phase is 0

onAdvance() method, returning false, hence phaser will continue

onAdvance() method is returning false, hence phaser will continue

------Phase-0 has been COMPLETED----------

Main thread has called arriveAndAwaitAdvance() and then called arriveAndDeregister(), now there is no thread registered with phaser.

Thread-2 - party has arrived and is working in Phase-1

Thread-1 - party has arrived and is working in Phase-1

Thread-3 - party has arrived and is working in Phase-1

onAdvance() method, current phase=1

Hence, we enter onAdvance() method and current phase is 1

if(phase==1 || registeredParties==0){

return true;

}

In if statement phase==1 will satisfy and phaser will return true.

onAdvance() method, returning true, hence phaser will terminate

onAdvance() method is returning true, hence phaser will terminate.

------Phase-1 has been COMPLETED----------

Application of Phaser in real world >

Software process management is done in phases.

First phase could be requirement gathering,

second could be software development and

third could be testing.

Second phase will not start until first is not completed, like wise third phase will not start until second is not completed.

SUMMARY>

In this thread concurrency tutorial we learned what is java.util.concurrent.Phaser in java with program and examples. We also wrote programs to demonstrate usage of Phaser in thread concurrency in java.

Having any doubt? or you you liked the tutorial! Please comment in below section.