Прерывая поток через фиксированное время, должен ли он генерировать исключение InterruptedException?
Я хочу прервать поток через фиксированное количество времени. Кто-то еще задал тот же вопрос, и ответ с самым высоким рейтингом ( /questions/19223002/kak-otklyuchit-potok/19223029#19223029) дал приведенное ниже решение, которое я немного сократил.
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;
}
}
Они добавили:
сон () не требуется. Это просто используется для SSCCE/ демонстрационных целей. Просто сделайте свое долгое бегущее задание прямо там, где спите ().
Но если вы замените Thread.sleep(4000);
с for (int i = 0; i < 5E8; i++) {}
тогда он не компилируется, потому что пустой цикл не генерирует исключение InterruptedException. И чтобы поток был прерываемым, он должен выдать исключение InterruptedException.
Есть ли способ заставить вышеуказанный код работать с общей долгосрочной задачей вместо sleep()
?
4 ответа
Если вы хотите, чтобы ваше действие было прерываемым (т. Е. Должна быть возможность прервать его до его завершения), вам нужно либо использовать другое прерываемое действие (Thread.sleep, InputStream.read, прочитать для получения дополнительной информации), либо вручную проверить состояние прерывания потока в Ваше состояние цикла, используя Thread.isInterrupted.
Вы можете проверить прерванное состояние потока, например:
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;
}
}
Вы неправильно поняли.
"... для прерывания потока необходимо выбросить исключение InterruptedException" просто не соответствует действительности. Этот блок улова существует только потому, что Thread.sleep()
метод бросков InterruptedException
, Если вы не используете сон (или любой другой код, который может бросить InterruptedException
), тогда вам не нужен блок catch.
Ни один код не скинет 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;
}