2017-08-09 67 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

我已更新文字以反映上述讨论。 –

相关问题