如何在Spring中检查@Async调用是否已完成?

时间:2015-03-21 09:16:25

标签: java spring spring-mvc asynchronous

我正在使用 @Async 注释执行rsync命令的方法。有十个线程一次调用此方法。我的要求是在所有十个线程完成rsync命令执行之后,只有我剩下的代码应该执行但是没有得到如何检查我的所有十个线程是否完全执行了@Async方法?所以请告诉我一个检查方法

2 个答案:

答案 0 :(得分:21)

如果要返回一些值,则应将返回值包装到标准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
}

答案 1 :(得分:-2)

如果您希望在完成此操作后完成代码,则不应使用@Async。如果由于某种原因异步调用此函数,则应从此方法返回Future并等待它返回某个值。