我希望能够取消标记有@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创建的内部线程 - 所以我没有办法取消它,是吗?
答案 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()
,如果是真的话就不要继续(结束操作)。