2011-01-09 5 views
25

Was ist der beste Weg, um eine synchrone Version einer asynchronen Methode in Java zu erstellen?Sync-Version der asynchronen Methode

Sagen Sie bitte eine Klasse mit diesen beiden Methoden haben:

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

Wie würden Sie eine synchrone doSomething() implementieren, die nicht zurück, bis die Aufgabe beendet ist?

Antwort

63

Werfen Sie einen Blick auf CountDownLatch. Sie können die gewünschte synchrone Verhalten mit so etwas wie dies emulieren:

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

Sie können auch das gleiche Verhalten erreichen mit CyclicBarrier mit 2 Parteien wie folgt aus:

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

Wenn Sie die Kontrolle über den Source-Code haben von asyncDoSomething() Ich würde jedoch empfehlen, es neu zu entwerfen, um stattdessen ein Future<Void> Objekt zurückzugeben. Auf diese Weise können Sie bei Bedarf zwischen asynchronem/synchronem Verhalten wechseln:

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

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

+1 Danke für solch eine detaillierte Antwort, Rodion! – hpique

+1

Ich wünschte, ich könnte dir mehr als 1 Stimme geben. Ausgezeichnete Empfehlung der Zukunft

+0

@rodion Wenn ich CountDownLatch innerhalb einer Schleife verwende und es innerhalb der Schleife instanziiert, wird es die Schleife daran hindern, die nächste Iteration auszuführen, bis die Iterationsaufgabe erledigt ist, oder es wird einfach weiter iterieren? Bitte lassen Sie mich wissen, wenn meine Frage nicht klar ist. – Aaron