I investigate Phaser from java.util.concurrent package and I wrote code sample:
public class ThreadsApp {
public static void main(String[] args) {
Phaser phaser = new Phaser(1);
new Thread(new PhaseThread(phaser, "PhaseThread 1")).start();
new Thread(new PhaseThread(phaser, "PhaseThread 2")).start();
// ждем завершения фазы 0
int phase = phaser.getPhase();
phaser.arriveAndAwaitAdvance();
System.out.println("phase " + phase + " finished");
// ждем завершения фазы 1
phase = phaser.getPhase();
phaser.arriveAndAwaitAdvance();
System.out.println("phase " + phase + " finished");
// ждем завершения фазы 2
phase = phaser.getPhase();
phaser.arriveAndAwaitAdvance();
System.out.println("phase " + phase + " finished");
phaser.arriveAndDeregister();
}
}
class PhaseThread implements Runnable {
Phaser phaser;
String name;
PhaseThread(Phaser p, String n) {
this.phaser = p;
this.name = n;
phaser.register();
}
public void run() {
try {
System.out.println(name + " start execute phase " + phaser.getPhase());
Thread.sleep(1000);
phaser.arriveAndAwaitAdvance(); // сообщаем, что первая фаза достигнута
System.out.println(name + " start execute phase " + phaser.getPhase());
Thread.sleep(2000);
phaser.arriveAndAwaitAdvance(); // сообщаем, что вторая фаза достигнута
System.out.println(name + " start execute phase " + phaser.getPhase());
Thread.sleep(3000);
phaser.arriveAndDeregister(); // сообщаем о завершении фаз и удаляем с регистрации объекты
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
output:
PhaseThread 2 start execute phase 0
PhaseThread 1 start execute phase 0
PhaseThread 2 start execute phase 1
phase 0 finished
PhaseThread 1 start execute phase 1
phase 1 finished
PhaseThread 1 start execute phase 2
PhaseThread 2 start execute phase 2
phase 2 finished
Output a bit distinct from desired by me:
I want :
PhaseThread 2 start execute phase 0
PhaseThread 1 start execute phase 0
phase 0 finished
PhaseThread 2 start execute phase 1
PhaseThread 1 start execute phase 1
phase 1 finished
PhaseThread 1 start execute phase 2
PhaseThread 2 start execute phase 2
phase 2 finished
Thus I want that phase X finished will be printed strict after both PhaseThread # start execute phase X and strict before PhaseThread # start execute phase X+1
I understand why my code works inproper but I don't know how to achieve desired behaviour. I think that it is possible because everywhere written that Phaser cover CyclicBarrier functionality.
Reading the Java Doc for Phaser shows an overridle method called
onAdvancewhich can be used to Print thephase X finishedwhen the phase is actually finished. Just modify the code as below.