TL;DR:在这种情况下Phaser.arriveAndDeregister()
,用于向移相器的等待者发出非阻塞信号,这对应于 operation CountDownLatch.countDown()
。
Phaser
和CountDownLatch
。首先要澄清的是 a通常Phaser
不能对 a 进行编码CountDownLatch
。与 a 同步的任务Phaser
必须相互等待(all-to-all 同步)。在 aCountDownLatch
中,有一组任务等待其他任务打开闩锁。
Phaser
和CyclicBarrier
。这两种机制都用于全对全同步。它们之间的两个区别是: 1)Phaser
使用移相器的任务集可能会在移相器的生命周期中增长,而CyclicBarrier
参与者的数量是固定的;2) 使用Phasers
,任务可以通知其他成员(参与者)并且只要它从该阶段取消注册就不会等待,而所有使用循环屏障的任务只能等待和通知。
用编码CountDownLatch
a Phaser
要使用移相器对 CountDownLatch(1) 进行编码,您需要记住以下几点:
- 聚会人数 = 服务员人数 + 1:已注册的聚会人数,无论是 via
new Phaser(PARTIES_COUNT)
还是 via Phaser.register
。
CountDown.await()
=Phaser.arriveAndAwaitAdvance()
CountDown.countDown()
=Phaser.arriveAndDeregister()
例子。假设您希望子任务等待父任务信号。使用CountDownLatch
你会写:
import java.util.concurrent.*;
class CountDownExample {
public static void main(String[] args) throws Exception {
CountDownLatch l = new CountDownLatch(1);
new Thread(() -> {
try {
l.await();
System.out.println("Child: running");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
System.out.println("Parent: waiting a bit.");
Thread.sleep(100);
l.countDown();
}
}
使用 aPhaser
你会写:
import java.util.concurrent.*;
class PhaserExample {
public static void main(String[] args) throws Exception {
Phaser ph = new Phaser(2); // 2 parties = 1 signaler and 1 waiter
new Thread(() -> {
ph.arriveAndAwaitAdvance();
System.out.println("Child: running");
}).start();
System.out.println("Parent: waiting a bit.");
Thread.sleep(100);
ph.arriveAndDeregister();
}
}
您可能想查看这篇文章以获取另一个示例。