1

例如,我希望找到一种@Async不绝对异步执行方法的方法。例如@Async,如果任务仍未完成,我想调用将阻止我的进程最多定义时间的任务。

@Async
public Future<ModelObject> doSomething() {
   //here we will block for a max allowed time if task still haven't been completed
}

所以这样的代码将是半异步的,但阻塞时间可以由开发人员控制。

PS:当然我可以通过在有限的时间内简单地阻塞调用线程来实现这一点。但我希望在弹簧层内实现这一点

4

2 回答 2

0

简而言之,不,没有办法配置 Spring 来做到这一点。

@Async注释由将工作AsyncExecutionInterceptor委托给AsyncTaskExecutor. 理论上,您可以编写自己的实现,AsyncTaskExecutor但即便如此,也无法使用@Async注释将所需的等待时间传递给您的执行程序。即使那样,我也不清楚调用者的界面会是什么样子,因为他们仍然会Future取回一个对象。您可能还需要对Future对象进行子类化。基本上,当您完成时,您将或多或少地从头开始重新编写整个功能。

您始终可以将返回的对象包装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
}

或者,如果您不想编写自己的课程,那么只需抓住TimeoutException.

Future<ModelObject> future = doSomething();
try {
    ModelObject result = future.get(3000,TimeUnit.MILLISECONDS);
    //Path B
} catch (TimeoutException ex) {
    //Path A
}
于 2013-04-07T12:17:55.700 回答
0

您可以使用返回 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";
        }
于 2016-01-20T18:10:42.047 回答