Wersja synchronizacji metody async

Jaki jest najlepszy sposób na stworzenie synchronicznej wersji metody asynchronicznej w Javie?

Powiedzmy, że masz klasę z tymi dwiema metodami:

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

Jak zaimplementowałbyś synchroniczny doSomething(), który nie powróci, dopóki zadanie nie zostanie ukończone?

Author: hpique, 2011-01-09

1 answers

Spójrz naCountDownLatch . Można emulować pożądane zachowanie synchroniczne za pomocą czegoś takiego:

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ąć to samo zachowanie używając CyclicBarrier z 2 takimi stronami:

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 kodem źródłowym asyncDoSomething(), zalecałbym jednak przeprojektowanie go, aby zamiast tego zwrócił obiekt Future<Void>. W ten sposób można łatwo przełączać się między zachowaniem asynchronicznym/synchronicznym w razie potrzeby w następujący sposób:

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

void synchronousMain() throws Exception{
  Future<Void> f = asyncDoSomething();
  //wait synchronously for result
  f.get();
}
 64
Author: rodion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-09 15:23:44