5

一定時間後にスレッドを中断したい。他の誰かが同じ質問をし、トップ投票の回答 ( https://stackoverflow.com/a/2275596/1310503 ) が以下の解決策を提供しました。

import java.util.Arrays;
import java.util.concurrent.*;

public class Test {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.invokeAll(Arrays.asList(new Task()), 2, TimeUnit.SECONDS);
        executor.shutdown();
    }
}

class Task implements Callable<String> {
    public String call() throws Exception {
        try {
            System.out.println("Started..");
            Thread.sleep(4000); // Just to demo a long running task of 4 seconds.
            System.out.println("Finished!");
        } catch (InterruptedException e) {
            System.out.println("Terminated!");
        }
        return null;
    }
}

彼らは次のように付け加えました。

sleep() は必要ありません。SSCCE/デモンストレーション目的でのみ使用されます。sleep()の代わりに、長時間実行されるタスクをすぐに実行してください。

ただし、空のループは InterruptedException をスローしないため、次のように置き換えるThread.sleep(4000);とコンパイルされません。for (int i = 0; i < 5E8; i++) {}また、スレッドを割り込み可能にするには、InterruptedException をスローする必要があります。

代わりに、一般的な長時間実行タスクで上記のコードを機能させる方法はありますsleep()か?

4

4 に答える 4

5

アクションを中断可能にする (つまり、完了する前に中断できるようにする) 場合は、他の中断可能なアクション (Thread.sleep、InputStream.read、read for more info ) を使用するか、スレッドの中断ステータスを手動で確認する必要があります。 Thread.isInterrupted を使用したサイクル条件。

于 2012-04-05T15:40:23.403 に答える
4

スレッドの中断ステータスを確認できます。次に例を示します。

public static void main(String[] args) throws Exception {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    executor.invokeAll(Arrays.asList(new Task()), 2, TimeUnit.SECONDS);
    executor.shutdown();
}

static class Task implements Callable<String> {

    public String call() throws Exception {
        System.out.println("Started..");
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("Interrupted!");
                return null;
            }
        }
        System.out.println("Finished!");
        return null;
    }
}
于 2012-04-05T15:42:56.427 に答える
3

あなたは誤解しました。

「...スレッドを割り込み可能にするには、InterruptedException をスローする必要があります」というのは、単純に正しくありません。その catch ブロックが存在するのは、Thread.sleep()メソッドが をスローするためだけInterruptedExceptionです。sleep (または をスローできるその他のコードInterruptedException) を使用していない場合は、catch ブロックは必要ありません。

于 2012-04-05T15:38:00.643 に答える
-2

InterruptedExceptionを置き換えても、どのコードもスローしませんsleep。の try-catch を削除する必要がありますInterruptedException

public String call() {
    System.out.println("Started..");
    for (int i = 0; i < 5E8; i++) {}
    System.out.println("Finished!");
    return null;
} 
于 2012-04-05T15:48:39.050 に答える