Phaser
パッケージから調べて、java.util.concurrent
コードサンプルを書きました:
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();
}
}
}
出力:
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
私が望むものとは少し異なる出力:
が欲しいです :
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
したがって、両方 の後に厳密に、前に厳密にphase X finished
印刷されることを望みますPhaseThread # start execute phase X
PhaseThread # start execute phase X+1
コードが不適切に動作する理由は理解していますが、目的の動作を実現する方法がわかりません。Phaser
随所に機能性を網羅していると書かれているのであり得ると思いCyclicBarrier
ます。