春天取消@异步任务 [英] Spring Cancel @Async Task

查看:70
本文介绍了春天取消@异步任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望将来可以取消带有@Async批注的方法.

I want to be able to cancel a method marked with the @Async annotation by it's future.

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

I have a Spring method marked with the @Async annotation. This method does some computation, and eventually returns a result. All examples I have seen recommend using the AsyncResult class to return this Future.

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

我以下列方式从另一个组件调用以下方法.出于示例目的,我希望立即取消该线程:

I call the following method, from another Component, in the following manner. For example purposes, I wish to immediately cancel this thread:

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

在这种情况下,该线程将永远不会被取消.这是因为,在这里查看AsyncResult的Spring实现:

In this case, the thread will never be cancelled. This is because, looking at the Spring implementation for AsyncResult here: https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java#L71 , this method doesn't actually do a single thing. It simply returns false, that the thread could not be cancelled. This is my problem. How can I cancel the Thread being created by the @Async method? I have no access to the internal thread being created by Spring - so I have no means myself with which to cancel it, do I?

推荐答案

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

Actually, Spring @Async uses a background thread pool of it's own. And as long as cancel() method of Future or shutdownNow() of executor service is concerned, Calling executor.shutdownNow() or future.cancel(true) don’t stop the ongoing thread immediately. What these methods do is simply call .interrupt() on the respective thread(s). And interrupts has no guaranteed immediate effect. It issues a flag so whenever in sleeping or waiting state, the thread will be stopped.

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

To be noted, If your tasks ignore the interruption, executor.shutdownNow() and future.cancel(true) will behave exactly the same way as executor.shutdown() and future.cancel(false).

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

If you need a way to stop the slow or blocking operation. If you have a long/endless loop, you can just add a condition whether Thread.currentThread().isInterrupted() and don’t continue if it is true(end the operation).

这篇关于春天取消@异步任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆