2013-04-07 36 views
1

例如我期望找到一种不完全异步执行方法。 例如,我想调用@Async任务,如果任务尚未完成,该任务将阻止我的进程达到最长限定的时间。java弹簧异步未来时间块

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

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

P.S:当然,我可以通过在有限的时间内阻止调用线程来实现这一点。但我期待在弹簧层内实现

+0

可能重复(HTTP:/ /stackoverflow.com/questions/3785197/providing-a-timeout-value-when-using-async-for-a-method-using-spring-3-0) – 2013-04-07 08:04:08

+0

没有。这不是重复的问题,因为如何限制整个异步任务执行的时间。 – 2013-04-07 08:35:48

回答

0

总之,没有办法配置Spring来做到这一点。

@Async注释由AsyncExecutionInterceptor处理,它将工作委托给AsyncTaskExecutor。理论上,您可以编写自己的AsyncTaskExecutor实现,但即使如此,也无法使用注释将期望的等待时间传递给执行程序。即使如此,我不清楚调用者的界面是什么样子,因为他们仍然会得到一个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 
} 
+0

辉煌!谢谢!! – 2013-04-07 15:27:36

0

您可以返回一个未来的@Async方法做到这一点:使用@Async为使用Spring 3.0的方法时提供的超时值]的

 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"; 
     }