Eche un vistazo a CountDownLatch. Puede emular el comportamiento síncrono deseado con algo como esto:
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();
}
También se puede conseguir el mismo comportamiento utilizando CyclicBarrier
con 2 partes de esta manera:
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();
}
Si usted tiene control sobre el código fuente de asyncDoSomething()
Sin embargo, recomendaría rediseñarlo para devolver un objeto Future<Void>
. De esta manera usted puede fácilmente cambiar entre el comportamiento síncrono/asíncrono cuando sea necesario así:
void asynchronousMain(){
asyncDoSomethig(); //ignore the return result
}
void synchronousMain() throws Exception{
Future<Void> f = asyncDoSomething();
//wait synchronously for result
f.get();
}
1 Gracias por una respuesta tan detallada, rodion! – hpique
Ojalá pudiera darle más de 1 voto. Excelente recomendación de Future –
@rodion si uso CountDownLatch dentro de un bucle, y lo instalé en el bucle, ¿evitará que el bucle ejecute la siguiente iteración hasta que la tarea de la iteración finalice o simplemente continuará iterando? Por favor, avíseme si mi pregunta no está clara. – Aaron