2011-01-09 10 views
25

¿Cuál es la mejor manera de hacer una versión síncrona de un método asíncrono en Java?Versión de sincronización del método async

Digamos que tiene una clase con estos dos métodos:

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

¿Cómo implementar un sincrónica doSomething() que no devuelve hasta que se termine la tarea?

Respuesta

63

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

1 Gracias por una respuesta tan detallada, rodion! – hpique

+1

Ojalá pudiera darle más de 1 voto. Excelente recomendación de Future

+0

@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

Cuestiones relacionadas