2017-08-09 66 views
-1

我明白我可以簡單地使用CountDownLatch直接,但是,作爲一個鍛鍊; Tibial和理解Phaser更好,我想用它代替的COuntDownLatchPhaser - 如何使用它作爲CountDownLatch(1)?

因此,我想創建N個awaiters的,這點需要翻轉閂一個線程。所有awaiters,如果翻轉之前到達,將阻塞,鎖存然而之後數下降,那麼以後所有await()回報瞬間。

Phaser我不知道如何實現這一點...屏障很容易,因爲我們有N + 1個線程,每個線程都到達並等待。然而,爲了確保沒有線程將後等待第一階段,不知何故我摸不透。

我能想出的唯一辦法,這是不是很好,如下:

Phaser p = new Phaser(1); 
int phase = p.getPhase(); 
.... 
// thread that awaits() 
new Thread(new Runnable() { 
    .... 
    p.awaitAdvance(phase) 
} 

而其他線程只是前進相位器下一個階段。這是不理想的,所以任何指針將不勝感激。

回答

0

TL; DR:在該上下文中使用Phaser.arriveAndDeregister()爲非阻塞信號到移相器,其對應於操作CountDownLatch.countDown()的服務員。

PhaserCountDownLatch澄清的第一件事是,Phaser不能通常編碼CountDownLatch。用Phaser同步的任務都必須等待對方(所有到所有同步)。在CountDownLatch中,有一組任務等待一些其他任務來打開鎖存器。

PhaserCyclicBarrier這兩種機制都用於全部同步。它們之間的兩個區別是:1)一個Phaser使用相位器的一組任務可能會在相位器的生命週期中增長,而在CyclicBarrier中,參與者的數量是固定; 2)與Phasers,任務可以通知其他成員(參與者),並且不等待,只要它從該相位器註銷,而使用循環屏障的所有任務只能等待並通知。

使用Phaser編碼CountDownLatch要編碼的CountDownLatch(1)你需要牢記以下移相器:註冊政黨的數量,或者通過new Phaser(PARTIES_COUNT)或通過Phaser.register

  1. 締約方數量=服務員+ 1的號碼。
  2. CountDown.await() = Phaser.arriveAndAwaitAdvance()
  3. 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

+0

這是不正確的 - 你的榜樣,你認爲是侍應生數提前,這是不是在COuntdownLatch的情況是已知的,該解決方案是不是一個通用的一個 – Bober02

+0

的一點是,有沒有**一般編碼**使用juc.Phasers編碼CountdownLatches。所以要麼a)我們犧牲表現力並引入爭用(通過選擇全部同步),或者我們需要事先知道多少參與者並獲得相同的爭用水平。 –

+0

我已更新文字以反映上述討論。 –

相關問題