2011-01-09 22 views
25

Jaki jest najlepszy sposób tworzenia synchronicznej wersji metody asynchronicznej w Javie?Wersja synchroniczna metody asynchronicznej

Powiedzmy, że masz klasę z tych dwóch metod:

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

Jak byś realizować synchroniczny doSomething() że nie zwraca aż zadanie zostanie zakończone?

Odpowiedz

63

Spójrz na CountDownLatch. Można emulować żądaną synchronicznego zachowanie z mniej więcej tak:

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

można również osiągnąć ten sam problem przy użyciu CyclicBarrier z 2 stron tak:

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

Jeśli masz kontrolę nad kodu źródłowego z asyncDoSomething() Zaleciłbym jednak przeprojektowanie go w celu zwrócenia obiektu Future<Void>. W ten sposób można łatwo przełączać się między zachowaniem asynchronicznym/synchronicznym, gdy jest to potrzebne:

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

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

+1 Dzięki za tak szczegółową odpowiedź, rodion! – hpique

+1

Chciałbym móc dać ci więcej niż 1 głos. Doskonała rekomendacja Future

+0

@rodion, jeśli użyję CountDownLatch wewnątrz pętli i utworzę instancję w pętli, czy zatrzyma ona pętlę od wykonania kolejnej iteracji, dopóki zadanie iteracji nie zostanie wykonane lub będzie dalej kontynuowało iterację? Daj mi znać, jeśli moje pytanie nie jest jasne. – Aaron

Powiązane problemy