我知道我可以直接使用 CountDownLatch
,但是,作为练习并为了更好地理解 Phaser
,我想使用它而不是 COuntDownLatch
。
因此,我将创建 N 个等待者,以及一个需要翻转锁存器的线程。所有等待者,如果在翻转之前到达,都会阻塞,但是在闩锁倒计时之后,所有后续的 await()
立即返回。
WIth Phaser
我不知道如何实现这一点...障碍很容易,因为我们有 N + 1 个线程,每个线程都到达并等待。然而,为了确保没有线程在第一阶段之后等待,不知何故,我感到困惑。
我能想到的唯一方法如下:
Phaser p = new Phaser(1);
int phase = p.getPhase();
....
// thread that awaits()
new Thread(new Runnable() {
....
p.awaitAdvance(phase)
}
另一个线程只是将移相器推进到下一阶段。这并不理想,因此我们将不胜感激。
最佳答案
我不同意@tiago-cogumbreiro 的回答。事实上,Phaser
可以用来模拟CountDownLatch
的行为。
您可以使用 Phaser 的 arrive()
方法来实现它。它不会等待其他线程到达。因此,可以实现 CountDownLatch
行为。
Phaser 的 arriveAndAwaitAdvance()
使调用它的线程等待,直到其他线程/方到达。因此,该方法可用于模拟 CyclicBarrier
的行为。
下面是使用 Phaser
模拟 CountDownLatch(3)
行为的源代码。如果只使用一个WorkerThread
,可以模拟CountDownLatch(1)
如果将 arrive()
方法替换为 arriveAndAwaitAdvance()
方法,下面的代码将模拟 CyclicBarrier
。
public class PhaserAsCountDownLatch {
static Phaser phaser = new Phaser(3);
public static void main(String[] args) {
new WorkerThread2().start();
new WorkerThread3().start();
new WorkerThread().start();
//waits till phase 0 is completed and phase is advanced to next.
phaser.awaitAdvance(0);
System.out.println("\nFROM MAIN THREAD: PHASE 0 COMPLETED");
System.out.println("FROM MAIN THREAD: PHASE ADVANCED TO 1");
System.out.println("MAIN THREAD ENDS HERE\n");
}
static class WorkerThread extends Thread{
@Override
public void run() {
for (int i = 1; i < 5; i++) {
System.out.println("tid: " + Thread.currentThread().getId() + ", BEFORE ARRIVING val is: " + i);
}
phaser.arrive();
System.out.println("ARRIVED tid: " + Thread.currentThread().getId());
}
}
static class WorkerThread2 extends Thread{
@Override
public void run() {
//won't wait for other threads to arrive. Hence, CountDownLatch behaviour can be achieved
phaser.arrive();
System.out.println("ARRIVED tid: " + Thread.currentThread().getId());
for (int i = 200; i < 231; i++) {
System.out.println("tid: " + Thread.currentThread().getId() + " AFTER ARRIVING. val is: " + i);
}
}
}
static class WorkerThread3 extends Thread{
@Override
public void run() {
//won't wait for other threads to arrive. Hence, CountDownLatch behaviour can be achieved
phaser.arrive();
System.out.println("ARRIVED tid: " + Thread.currentThread().getId());
for (int i = 300; i < 331; i++) {
System.out.println("tid: " + Thread.currentThread().getId() + " AFTER ARRIVING. val is: " + i);
}
}
}
}
关于java - Phaser - 如何将其用作 CountDownLatch(1)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45600243/