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 Grazie per una risposta così dettagliata, Rodion! – hpique
Vorrei poterti dare più di 1 voto. Ottima raccomandazione del futuro –
@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