[英]java spring async future block on timely manner
eg I looking to find a way to execute @Async
method not absolutely asynchronously. 例如,我正在寻找一种方法,而不是绝对异步地执行@Async
方法。 For example I want to invoke @Async
task that will block my process for a up to a maximum defined time if task still haven't completed. 例如,我想调用@Async
任务,如果任务仍未完成,它将在最长的定义时间内阻止我的进程。
@Async
public Future<ModelObject> doSomething() {
//here we will block for a max allowed time if task still haven't been completed
}
So such code will be semi asynchronous but the blocking time can be controlled by developer. 这样的代码将是半异步的,但是阻塞时间可以由开发人员控制。
PS : of course I can achieve this by simply blocking calling thread for a limited time. PS:当然,我可以通过在有限的时间内阻塞调用线程来实现此目的。 but I look to achieve that within spring layer 但我希望在弹簧层内实现这一目标
In short, no, there is no way to configure Spring to do this. 简而言之,没有,没有办法配置Spring来做到这一点。
The @Async
annotation is handled by the AsyncExecutionInterceptor
which delegates the work to a AsyncTaskExecutor
. @Async
批注由AsyncExecutionInterceptor
处理,该工作将工作委派给AsyncTaskExecutor
。 You could, in theory, write your own implementation of the AsyncTaskExecutor
but even then there would be no way to use the @Async
annotation to pass the desired wait time to your executor. 从理论上讲,您可以编写自己的AsyncTaskExecutor
实现,但是即使那样,也无法使用@Async
注释将所需的等待时间传递给执行程序。 Even then, it's not clear to me what the caller's interface would look like since they'd still be getting a Future
object back. 即使那样,我仍然不清楚调用者的界面是什么样子,因为他们仍将找回Future
对象。 You would probably also need to subclass the Future
object as well. 您可能还需要对Future
对象进行子类化。 Basically, by the time you are finished, you will have written the entire feature again more or less from scratch. 基本上,到您完成时,您将或多或少地从头开始编写整个功能。
You could always wrap the returned Future
object in your own WaitingFuture
proxy which provides an alternate get implementation although even then you'd have no way of specifying the wait value on the callee side: 您始终可以将返回的Future
对象包装在您自己的WaitingFuture
代理中,该代理提供替代的get实现,尽管即使这样,您也无法在被调用方指定等待值:
WaitingFuture<ModelObject> future = new WaitingFuture<ModelObject>(service.doSomething());
ModelObject result = future.get(3000); //Instead of throwing a timeout, this impl could just return null if 3 seconds pass with no answer
if(result == null) {
//Path A
} else {
//Path B
}
Or if you don't want to write your own class then just catch the TimeoutException
. 或者,如果您不想编写自己的类,则只需捕获TimeoutException
。
Future<ModelObject> future = doSomething();
try {
ModelObject result = future.get(3000,TimeUnit.MILLISECONDS);
//Path B
} catch (TimeoutException ex) {
//Path A
}
You can do it with an @Async method that returns a Future: 您可以使用返回Future的@Async方法来执行此操作:
Future<String> futureString = asyncTimeout(10000);
futureString.get(5000, TimeUnit.MILLISECONDS);
@Async
public Future<String> asyncTimeout(long mills) throws InterruptedException {
return new AsyncResult<String>(
sleepAndWake(mills)
);
}
public String sleepAndWake(long mills) throws InterruptedException{
Thread.sleep(mills);
return "wake";
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.