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

指定されたタイムアウト (10 秒) まで while ループを実行します。

リクエストがタイムアウトすると、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->");
}

私の問題は、タイムアウト(ハンドルタイムアウトメソッドの実行が終了した)応答がhandletimeoutメソッドから送信された後でも、iの値がゼロ以外の値に変更されるまで、whileループがまだ処理されていることです。

リクエストはまだサーバーによって保持されていますか?では、リクエストタイムアウトの使用は何ですか?

前もって感謝します...

4

1 に答える 1

2

サーブレット コンテナー スレッドは、async 呼び出し可能オブジェクトがタイムアウトしたことを検出すると、handleTimeout() を (独自のコンテキストで) 呼び出します。これが、handleTimeout() が実行されるのを見る理由です。これは、Callable を実行するスレッドではなく、サーブレット コンテナー スレッドによって実行されます。

カスタムのタイムアウト処理が必要な場合は、次の 2 つのことを行う必要があります。

  1. WebAsyncTask で onTimeout() をオーバーライドします。onTimeout() へのコールバックとして提供する呼び出し可能オブジェクトは、呼び出し可能オブジェクトがタイムアウトになったことを検出すると、サーブレット コンテナー スレッド内で呼び出されます。
  2. コントローラー内で作成した Callable のタイムアウト/中断を確認します。Callable が割り込みを予期せず、尊重しない場合 (「ターゲット スレッドが割り込みステータスをポーリングしない場合、割り込みは事実上無視されます」)、割り込みを行う方法はありません。中断を予期して尊重する方法を知るために、この回答を参照してください。
于 2013-04-23T22:16:49.777 に答える