我已经实现了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();
我有几个问题:
arrive()
而调用arriveAndAwaitAdvance()
和register()
是不正确的。 changed()
可能为同一事件多次调用。我希望await()
之一可能由于先前的事件而立即返回。 对这个问题有任何想法吗?
最佳答案
关于您的第一个问题: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