2

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

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

}

来源:我已经换了

Thread.sleep(2000)

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

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

请求是否仍然被服务器持有?那么请求超时有什么用?

提前致谢...

4

1 回答 1

2

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

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

  1. 在您的 WebAsyncTask 中覆盖 onTimeout()。当检测到您的可调用对象已超时时,您提供的作为 onTimeout() 回调的任何可调用对象都将在 servlet 容器线程中被调用。
  2. 检查您在控制器内创建的 Callable 中的超时/中断。如果您的 Callable 不期望并尊重中断(“如果目标线程不轮询中断状态,则中断被有效忽略”),则无法中断它!请参考答案以了解如何期望和尊重中断。
于 2013-04-23T22:16:49.777 回答