Как остановить нить с помощью interrupt
Разбираюсь с нитями. На сколько я понял, interrupt, по сути, не останавливает нить. Это всего лишь флаг, который показывает, что мы хотим ее остановить. А уж как мы ее остановим, это уже наши проблемы. В каком-то смысле, это можно представить себе, как if else. Да, ветка else есть, в тоже время, что в ней будет, мы должны указать сами. Или может быть try catch — что будет, если возникнет исключение, мы должны указать сами. Таким образом, если у нас, допустим, есть код:
public class Solution {
public static void main(String[] args) throws InterruptedException {
TestThread testThread = new TestThread();
testThread.start();
testThread.interrupt();
}
public static class TestThread extends Thread {
@Override
public void run() {
while (!this.isInterrupted()) {
}
}
}
}
то testThread.interrupt() не останавливает нить, а всего лишь дает нам "инструмент", условие, намерение, флаг, а останавливаем ее мы сами в методе run() класса нити. Тогда зачем вообще эти interrupt, interrupted, isInterrupted нужны? Если мы все делаем сами. Мы могли создать и назвать boolean как угодно.
Плюс, я так понимаю, есть нюанс с методом Thread.sleep, который проверяет флаг. И благодаря этом, работает вот такое прерывание:
public class Solution {
public static volatile int numSeconds = 4;
public static void main(String[] args) throws InterruptedException {
RacingClock clock = new RacingClock();
Thread.sleep(3500);
clock.interrupt();
}
public static class RacingClock extends Thread {
public RacingClock() {
start();
}
public void run() {
for (; numSeconds > 0; numSeconds--) {
System.out.print(numSeconds + " ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Прервано!");
return;
}
}
System.out.println("Марш!");
}
}
}
то есть, насколько я понимаю из-за Thread.sleep(3500) в main в run класса нити мы ловим исключение и проходим по catch. Ну и нюанс, что interrupted после проверки очищает флаг (устанавливает false), поэтому, в случае проверки, флаг необходимо будет восстановить. Правильно ли я рассуждаю?
Ответы (1 шт):
Метод interrupt() не устанавливает никаких флагов для остановки потока, а берет и прерывает поток путем возбуждения исключения InterruptedException, и т.к. исключения из потоков не выбрасываются выше, то исключение заставляет поток прервать свою работу до завершения блока метода run(), одновременно с этим для потока устанавливается флаг прерванного потока, и метод isInterrupted() возвращает нам true.
Thread.sleep() используется в блоке try-catch потому что метод sleep() выбрасывает исключение InterruptedException, для того, чтобы при выходе из блокировки (а поток блокируется на время сна) проверить, а жив ли еще поток.
Как реализован метод isInterrupted() внутри, я не скажу, он нативный, меня это не интересовало.