web-dev-qa-db-ja.com

@Async呼び出しがSpringで完了したことを確認するにはどうすればよいですか?

私はrsyncコマンドを実行するメソッドに@ Asyncアノテーションを使用しています。一度にこのメソッドを呼び出す10スレッドがあります。私の要件は、10個のスレッドすべてがrsyncコマンドの実行を完了した後、残りのコードのみを実行する必要がありますが、10個のスレッドすべてが@Asyncメソッドを完全に実行したかどうかを確認する方法がありませんか?それをチェックする方法を教えてください

11
DnA

値を返す場合は、戻り値をStandard Java SE FutureまたはSpringの AsyncResult にラップする必要があります。 Futureも実装しています。

このようなもの:

_@Component
class AsyncTask {
  @Async
  public Future<String> call() throws InterruptedException {
    return new AsyncResult<String>("return value");
  }
}
_

これが適切な場合は、呼び出し元で次のようにします。

_public void kickOffAsyncTask() throws InterruptedException {
  Future<String> futureResult =  asyncTask.call();

  //do some stuff in parallel

  String result = futureResult.get();
  System.out.println(result);
}
_

futureResult.get()を呼び出すと、呼び出し元のスレッドがブロックされ、非同期スレッドが完了するまで待機します。

永遠に待ちたくない場合は、オプションでFuture.get(long timeout, TimeUnit unit)を使用できます。

編集:

値を返す必要がない場合でも、ダミーの戻り値を返すことを検討することをお勧めします。何かのためにそれを使用する必要はなく、特定のスレッドが完了したことを示すために使用するだけです。このようなもの:

_public void kickOffAsyncTasks(int execCount) throws InterruptedException {
  Collection<Future<String>> results = new ArrayList<>(execCount);

  //kick off all threads
  for (int idx = 0; idx < execCount; idx++) {
    results.add(asyncTask.call());
  }

  // wait for all threads
  results.forEach(result -> {
    try {
      result.get();
    } catch (InterruptedException | ExecutionException e) {
      //handle thread error
    }
  });

  //all threads finished
}
_
24
luboskrnac