2

我已经实现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. changed()可能会为同一事件多次调用。我希望其中一个await()可能会因为以前的事件而立即返回。

关于这个问题的任何想法?

4

1 回答 1

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
于 2013-10-24T12:33:50.663 回答