Подтвердить что ты не робот

Синхронная версия асинхронного метода

Какой лучший способ сделать синхронную версию асинхронного метода в Java?

Скажем, у вас есть класс с этими двумя методами:

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

Как бы вы реализовали синхронный doSomething(), который не возвращается до завершения задачи?

4b9b3361

Ответ 1

Посмотрите 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 с двумя сторонами, такими как:

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