我已经实现了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()
中的一个可能由于之前的事件而无法返回。对此问题有任何想法吗?
答案 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