如何正确使用Phaser?

时间:2013-10-24 09:25:26

标签: java multithreading asynchronous concurrency phaser

我已经实现了MyListener,可以从两个不同的线程访问。

class MyListener implements Listener {
    private final Phaser phaser = new Phaser(2);        

    @Override
    public void changed () {
        phaser.arrive();
    }

    public void await () {
        phaser.arriveAndAwaitAdvance();    
    } 
}

我在主线程中使用它

MyListener listener = new Listener();
someObject.setListener(listener);     

doSomething(); //it would result in Listener.changed() being invoked
listener.await();

doSomething(); //it would result in Listener.changed() being invoked
listener.await();

我有几个问题:

  1. Java文档声明,在不首先调用arrive()的情况下调用arriveAndAwaitAdvance()register()是不正确的。
  2. 对于同一事件,可能会多次调用
  3. changed()。我希望await()中的一个可能由于之前的事件而无法返回。
  4. 对此问题有任何想法吗?

1 个答案:

答案 0 :(得分:1)

关于您的第一个问题:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Phaser.html#arrive()

表示:

  

未注册方调用此方法时出现使用错误。

并未声明必须通过致电register()进行注册。在指定构造函数中预先注册的参与方数量是有效用法。


关于第二项,您不得多次致电arrive。目前尚不清楚你对一个事件多次调用changed()的意图是什么意思,是否允许另一个线程在第一次调用时继续,最后一个(如何知道它是最后一个?)或者介于两者之间?

您似乎希望分割到达,即让其他进程有权继续等待此权限。这很简单:不要使用化合物arriveAndAwaitAdvance()

int currentPhase = phaser.arrive(); // allow the other thread to proceed
…
phaser.awaitAdvance(currentPhase); // wait for the other thread’s arrival