spring MVC Callable执行会在请求超时后继续执行吗?

时间:2013-04-19 09:08:11

标签: spring spring-mvc asynchronous

我有一个像这样的异步处理程序方法

@RequestMapping("/custom-timeout-handling")
public @ResponseBody WebAsyncTask<String> callableWithCustomTimeoutHandling() {

    Callable<String> callable = new Callable<String>() {

        public String call() throws Exception {
            while(i==0){
            System.out.println("inside while loop->");
            }

            return "Callable result";
        }
    };

    return new WebAsyncTask<String>(10000, callable);
}

将执行while循环,直到指定的超时(10秒)。

当请求超时时,它会从TimeoutCallableProcessingInterceptor执行handleTimeout方法

public class TimeoutCallableProcessingInterceptor extends CallableProcessingInterceptorAdapter {

@Override
public <T> Object handleTimeout(NativeWebRequest request, Callable<T> task) throws Exception {
    throw new IllegalStateException("[" + task.getClass().getName() + "] timed out");
}

}

Source:我已经取代了

Thread.sleep(2000)

while(i==0){
System.out.println("inside while loop->");
}

我的问题是甚至在超时(完成执行句柄超时方法)响应从handletimeout方法发送之后 while循环仍在处理,直到i的值更改为零以外的其他值。

请求是否仍然由服务器保存?那么请求超时的用途是什么?

提前致谢...

1 个答案:

答案 0 :(得分:2)

当servlet容器线程检测到异步可调用超时时,它会调用handleTimeout()(在其自己的上下文中)。这就是你看到handleTimeout()被执行的原因。它由servlet容器线程执行,而不是由运行Callable的线程执行。

如果您想要自定义超时处理,则需要做两件事:

  1. 覆盖WebAsyncTask中的onTimeout()。无论你提供什么可调用因为onTimeout()的回调都会在检测到你的callable超时时在servlet容器线程中被调用。
  2. 检查您在控制器内创建的Callable中的超时/中断。 如果您的Callable不期望并且不尊重中断(“如果目标线程没有轮询中断状态,则中断被有效忽略”),则无法中断它!请参考this回答,了解如何期待和尊重中断。