弹簧取消@Async任务

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

我有一个用注释标记的Spring方法。此方法执行一些计算,并最终返回结果。我看到的所有示例都建议使用该类返回此 Future。@AsyncAsyncResult

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

我通过以下方式从另一个组件调用以下方法。例如,我希望立即取消此线程:

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

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


答案 1

实际上,Spring使用了自己的后台线程池。只要涉及Future的unase()方法或执行器服务的sucdownNow(),调用就不会立即停止正在进行的线程。这些方法的作用是简单地调用相应的线程。并且没有保证立即生效。它会发出一个标志,因此每当处于睡眠或等待状态时,线程将被停止。@Asyncexecutor.shutdownNow() or future.cancel(true).interrupt()interrupts

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

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


答案 2

推荐