Spring取消@Async任务

时间:2016-08-10 17:37:26

标签: java spring multithreading spring-mvc asynchronous

我希望能够取消标记有@Async注释的方法。

我有一个标有@Async注释的Spring方法。此方法执行一些计算,并最终返回结果。我见过的所有示例都建议使用AsyncResult类来返回此Future。

@Async
public Future<String> run() {
    // ... Computation. Minutes pass ...
    return new AsyncResult<String>("Result");
}

我通过以下方式从另一个Component调用以下方法。例如,我希望立即取消这个帖子:

Future<String> future = component.run();
future.cancel(true);

在这种情况下,线程永远不会被取消。这是因为,查看AsyncResult的Spring实现:https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java#L71,此方法实际上并不做任何事情。它只返回false,表示线程无法取消。这是我的问题。如何取消@Async方法创建的线程?我无法访问Spring创建的内部线程 - 所以我没有办法取消它,是吗?

1 个答案:

答案 0 :(得分:6)

实际上,Spring @Async使用它自己的后台线程池。并且只要涉及Future的cancel()方法或执行程序服务的shutdownNow(),调用executor.shutdownNow() or future.cancel(true)不会立即停止正在进行的线程。这些方法的作用只是在相应的线程上调用.interrupt()。并且interrupts 没有保证立即效果。它会发出一个标志,所以无论何时处于休眠或等待状态,线程都会被停止。

需要注意的是,如果您的任务忽略了中断,executor.shutdownNow() and future.cancel(true)的行为方式与executor.shutdown() and future.cancel(false)完全相同。

如果您需要一种方法来阻止缓慢或阻塞操作。如果你有一个很长/无限循环,你可以添加一个条件是Thread.currentThread().isInterrupted(),如果是真的话就不要继续(结束操作)。