我调查了 java.util.concurrent
包中的 Phaser
并编写了代码示例:
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 finish
将在 PhaseThread # startexecute stage X
和 strict before PhaseThread strict after 之间打印# 开始执行阶段X+1
我明白为什么我的代码工作不正常,但我不知道如何实现所需的行为。我认为这是可能的,因为到处都写有 Phaser
涵盖 CyclicBarrier
功能。
最佳答案
阅读 Phaser 的 Java 文档显示了一个名为 onAdvance
的重写方法,该方法可用于在阶段实际完成时打印 X 阶段完成
。只需修改如下代码即可。
public class ThreadsApp {
public static void main(String[] args) {
Phaser phaser = new Phaser(1) {
protected boolean onAdvance(int phase, int parties) {
System.out.println("phase " + phase + " finished");
return false;
}
};
new Thread(new PhaseThread(phaser, "PhaseThread 1")).start();
new Thread(new PhaseThread(phaser, "PhaseThread 2")).start();
// ждем завершения фазы 0
int phase = phaser.getPhase();
phaser.arriveAndAwaitAdvance();
// ждем завершения фазы 1
phase = phaser.getPhase();
phaser.arriveAndAwaitAdvance();
// ждем завершения фазы 2
phase = phaser.getPhase();
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();
}
}
}
关于阶段终止后的 java.util.concurrent.Phaser 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41894225/