2011-01-09 4 views
25

Qual è il modo migliore per creare una versione sincrona di un metodo asincrono in Java?Versione di sincronizzazione del metodo asincrono

Dire che hai una classe con questi due metodi:

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

Come vuoi implementare un sincrono doSomething() che non restituisce fino a quando il compito è finito?

risposta

63

Dai un'occhiata allo CountDownLatch. È possibile emulare il comportamento sincrono desiderato con qualcosa di simile:

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

È anche possibile ottenere lo stesso comportamento utilizzando CyclicBarrier con 2 parti in questo modo:

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

Se avete il controllo del codice sorgente di asyncDoSomething() Tuttavia, consigliamo di riprogettarlo per restituire un oggetto Future<Void>. In questo modo si potrebbe facilmente passare da un comportamento sincrono asincrono/quando necessario in questo modo:

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

void synchronousMain() throws Exception{ 
    Future<Void> f = asyncDoSomething(); 
    //wait synchronously for result 
    f.get(); 
} 
+1

1 Grazie per una risposta così dettagliata, Rodion! – hpique

+1

Vorrei poterti dare più di 1 voto. Ottima raccomandazione del futuro

+0

@rodion se utilizzo CountDownLatch all'interno di un ciclo e lo istanziato all'interno del ciclo, interromperà il ciclo dall'esecuzione dell'iterazione successiva fino a quando l'attività dell'iterazione non sarà completata o continuerà semplicemente a iterare? Per favore fatemi sapere se la mia domanda non è chiara. – Aaron