异步方法的同步版本

31

如何在Java中创建异步方法的同步版本?

假设您有一个包含以下两个方法的类:

asyncDoSomething(); // Starts an asynchronous task
onFinishDoSomething(); // Called when the task is finished 

如何实现一个同步的doSomething()方法,在任务完成之前不返回任何结果?

1个回答

76

看一下CountDownLatch。你可以用类似这样的方式模拟所需的同步行为:

private CountDownLatch doneSignal = new CountDownLatch(1);

void main() throws InterruptedException{
  asyncDoSomething();
  //wait until doneSignal.countDown() is called
  doneSignal.await();
}

void onFinishDoSomething(){
  //do something ...
  //then signal the end of work
  doneSignal.countDown();
}

您也可以使用带有2个参与者的CyclicBarrier来实现相同的行为,如下所示:

private CyclicBarrier barrier = new CyclicBarrier(2);

void main() throws InterruptedException{
  asyncDoSomething();
  //wait until other party calls barrier.await()
  barrier.await();
}

void onFinishDoSomething() throws InterruptedException{
  //do something ...
  //then signal the end of work
  barrier.await();
}
如果你有 asyncDoSomething() 的源代码控制权,我建议将其重新设计为返回一个 Future<Void> 对象。这样做可以在需要时轻松切换异步/同步行为,如下所示:
void asynchronousMain(){
  asyncDoSomethig(); //ignore the return result
}

void synchronousMain() throws Exception{
  Future<Void> f = asyncDoSomething();
  //wait synchronously for result
  f.get();
}

1
希望我能给你超过1票。Future<Void>的优秀推荐。 - AZ_
@rodion 如果我在循环中使用CountDownLatch,并在循环内部实例化它,那么它会阻止循环执行下一次迭代,直到该迭代的任务完成,还是仅继续迭代?如果我的问题不清楚,请告诉我。 - Aaron
一个信号量也可以起到同样的作用。 - Zixradoom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接