6

を探索しているときに、を受け入れるExecutorServiceメソッドに遭遇しました。Future.get()timeout

このメソッドのJavaドキュメントは言う


必要に応じて、計算が完了するまで指定された時間だけ待機し、可能な場合はその結果を取得します。

パラメーター:

timeout最大待機時間

unitタイムアウト引数の時間単位


私の理解によると、私たちは にタイムアウトを課しており、指定された時間 (タイムアウト) が経過した後に中断するようcallableに に送信します。ExecutorServicecallable

しかし、以下のコードによるとlongMethod()、タイムアウト (2 秒) を超えて実行されているようで、これを理解するのに本当に混乱しています。誰でも私に正しい道を教えてもらえますか?

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Timeout implements Callable<String> {

    public void longMethod() {
        for(int i=0; i< Integer.MAX_VALUE; i++) {
            System.out.println("a");
        }
    }

    @Override
    public String call() throws Exception {
        longMethod();
        return "done";
    }


    /**
     * @param args
     */
    public static void main(String[] args) {
        ExecutorService service = Executors.newSingleThreadExecutor();

        try {
            service.submit(new Timeout()).get(2, TimeUnit.SECONDS);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
4

3 に答える 3

14

指定された時間(タイムアウト)が経過した後、呼び出し可能オブジェクトが中断します

違います。タスクは引き続き実行されますが、タイムアウト後に null 文字列が表示されます。

キャンセルしたい場合:

  timeout.cancel(true) //Timeout timeout = new Timeout();

PSあなたが今持っているように、この割り込みはこれまで何の効果もありません。あなたはそれを決してチェックしていません。

たとえば、次のコードは割り込みを考慮しています。

    private static final class MyCallable implements Callable<String>{

    @Override
    public String call() throws Exception {
        StringBuilder builder = new StringBuilder();
        try{
            for(int i=0;i<Integer.MAX_VALUE;++i){
                builder.append("a");
                Thread.sleep(100);
            }
        }catch(InterruptedException e){
            System.out.println("Thread was interrupted");
        }
        return builder.toString();
    }
}

その後:

        ExecutorService service = Executors.newFixedThreadPool(1);
    MyCallable myCallable = new MyCallable();
    Future<String> futureResult = service.submit(myCallable);
    String result = null;
    try{
        result = futureResult.get(1000, TimeUnit.MILLISECONDS);
    }catch(TimeoutException e){
        System.out.println("No response after one second");
        futureResult.cancel(true);
    }
    service.shutdown();
于 2013-04-29T11:15:35.070 に答える