Посмотрите на 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();
}
Если у вас есть контроль над исходным кодом из 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 Спасибо за такой подробный ответ, родион! – hpique
Хотел бы я дать вам более 1 голоса. Отличная рекомендация Future –
@rodion, если я использую CountDownLatch внутри цикла и создаст его в цикле, остановит цикл от выполнения следующей итерации до выполнения итерации или продолжит итерацию? Пожалуйста, дайте мне знать, если мой вопрос не ясен. – Aaron