2011-01-09 137 views
25

在Java中製作異步方法的同步版本的最佳方式是什麼?異步方法的同步版本

說你有這兩種方法的類:

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

你會如何實現同步doSomething()不返回,直到任務完成?

回答

63

看看CountDownLatch

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

您也可以實現用CyclicBarrier與兩方這樣相同的行爲:

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

如果你有在源代碼控制你可以用這樣的模擬所需的同步行爲asyncDoSomething()但是,我會建議重新設計它,而不是返回一個Future<Void>對象。通過這樣做,您可以在需要時輕鬆地在異步/同步行爲之間切換,如下所示:

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

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

+1感謝您的詳細解答,rodion! – hpique 2011-01-09 15:30:22