30

Javaで非同期メソッドの同期バージョンを作成する最良の方法は何ですか?

次の 2 つのメソッドを持つクラスがあるとします。

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

doSomething()タスクが完了するまで戻らない同期をどのように実装しますか?

4

1 に答える 1

74

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();
}

CyclicBarrier次のように 2 つのパーティを使用して、同じ動作を実現することもできます。

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();
}

If you have control over the source-code of asyncDoSomething() I would, however, recommend redesigning it to return a Future<Void> object instead. By doing this you could easily switch between asynchronous/synchronous behaviour when needed like this:

void asynchronousMain(){
  asyncDoSomethig(); //ignore the return result
}

void synchronousMain() throws Exception{
  Future<Void> f = asyncDoSomething();
  //wait synchronously for result
  f.get();
}
于 2011-01-09T15:10:50.487 に答える