java - 如何正确使用Phaser?

标签 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. changed() 可能会为同一事件调用多次。我预计 await() 中的一个可能会因为之前的事件而立即返回。

对这个问题有什么想法吗?

最佳答案

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

说:

It is a usage error for an unregistered party to invoke this method.

它没有声明必须通过调用 register() 来进行注册。像您一样在构造函数中指定预注册方的数量是一种有效的用法。


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

看来你想把到达分开,即给其他进程继续的权利,从等待这个许可。这很简单:不要使用复合 arriveAndAwaitAdvance():

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

关于java - 如何正确使用Phaser?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19561973/

相关文章:

java - 多线程不起作用。什么是不正确的?

java - 使用预定义 key 锁定的竞争条件解决方案

node.js - Node FTP : Multiple asynchronous calls inside loop

android - 异步任务方法调用在 android 中非常慢

用于模糊比较文本字符串的 Java 库

java - 使用巨大的 map (putIfAbsent)

java - 缺少方法体,或在 Java 中声明抽象

c++ - 随着实体数量的增加,物理代码变得越来越慢

java - 从 ScheduledExecutorService 中提取异常

c# - 将 .NET 类库转变为多线程 .NET 类库的最佳实践