TL; DR:在該上下文中使用Phaser.arriveAndDeregister()
爲非阻塞信號到移相器,其對應於操作CountDownLatch.countDown()
的服務員。
Phaser
和CountDownLatch
。澄清的第一件事是,Phaser
不能通常編碼CountDownLatch
。用Phaser
同步的任務都必須等待對方(所有到所有同步)。在CountDownLatch
中,有一組任務等待一些其他任務來打開鎖存器。
Phaser
和CyclicBarrier
。這兩種機制都用於全部同步。它們之間的兩個區別是:1)一個Phaser
使用相位器的一組任務可能會在相位器的生命週期中增長,而在CyclicBarrier
中,參與者的數量是固定; 2)與Phasers
,任務可以通知其他成員(參與者),並且不等待,只要它從該相位器註銷,而使用循環屏障的所有任務只能等待並通知。
使用Phaser
編碼CountDownLatch
。要編碼的CountDownLatch(1)你需要牢記以下移相器:註冊政黨的數量,或者通過new Phaser(PARTIES_COUNT)
或通過Phaser.register
:
- 締約方數量=服務員+ 1的號碼。
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();
}
}
使用Phaser
你可以這樣寫:
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();
}
}
你可能想看看this post for another example。
這是不正確的 - 你的榜樣,你認爲是侍應生數提前,這是不是在COuntdownLatch的情況是已知的,該解決方案是不是一個通用的一個 – Bober02
的一點是,有沒有**一般編碼**使用juc.Phasers編碼CountdownLatches。所以要麼a)我們犧牲表現力並引入爭用(通過選擇全部同步),或者我們需要事先知道多少參與者並獲得相同的爭用水平。 –
我已更新文字以反映上述討論。 –