Метод interrupt

Модуль 2. Java Core
11 уровень , 4 лекция
Открыта

— Привет, Амиго! Согласись, Элли хорошо придумала с этим Cancel?

— Ага.

— На самом деле нечто подобное существует в классе Thread. Только переменная называется не isCancel, а isInterrupted, и метод остановки, соответственно, не cancel(), а interrupt().

— Да?

— Ага. Вот смотри:

Код Описание
class Clock implements Runnable {
  public void run() {
    Thread current = Thread.currentThread();

    while (!current.isInterrupted()) {
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
        current.interrupt();
      }
      System.out.println("Tik");
  }
  }
}
Т.к. много нитей могут вызвать метод run одного объекта, то объект Clock в своем методе run получает объект вызвавшей его нити («текущей нити»).

Класс Clock (часы) будет писать в консоль раз в секунду слово «Tik», пока переменная isInterrupted текущей нити равна false.

Когда переменная isInterrupted станет равной true, метод run завершится.


public static void main(String[] args) throws Exception {
    Clock clock = new Clock();
    Thread clockThread = new Thread(clock);
    clockThread.start();


    Thread.sleep(10000);
    clockThread.interrupt();
}
       
Главная нить, запускает дочернюю нить – часы, которая должна работать вечно.

Ждет 10 секунд и отменяет задание, вызовом метода interrupt.

Главная нить завершает свою работу.

Нить часов завершает свою работу.

Более того, в методе sleep, который так любят использовать для организации вечного цикла в методе run, есть автоматическая проверка переменной isInterrupted. Если нить вызовет метод sleep, то этот метод сначала проверит, а не установлена ли для текущей (вызвавшей его нити) переменная isInterrupted в true. И если установлена, то метод не будет спать, а выкинет исключение InterruptedException.

— А зачем выкидывать исключение? Не лучше ли тоже просто в цикле вместо isCancel подставить isInterrupted()?

— Во-первых, не всегда в методе run есть цикл. Метод может состоять просто из двух десятков вызовов других методов. Тогда перед вызовом каждого придется добавлять проверку isInterrupted.

Во-вторых, вдруг какой-то метод очень долго исполняется, т.к. делает много разных действий.

В-третьих, выкидывание исключения – это не замена проверке isInterrupted, а скорее удобное дополнение. Выкинутое исключение позволяет быстро раскрутить стек вызовов до самого run.

В-четвертых, метод sleep часто используют, и, получается, к такому полезному методу неявно добавили не менее полезную проверку. Вроде бы никто специально проверку не добавлял, а она есть. Это очень ценно, когда ты используешь много чужого кода и не можешь сам добавить в него проверку.

В-пятых, дополнительная проверка не приводит к снижению производительности. Вызов метода sleep значит, что нить должна ничего не делать (спать), поэтому дополнительная работа никому не мешает.

— Серьёзные аргументы.

— И, наконец, последнее: ты можешь в своем методе run вызывать чужой код, к которому у тебя нет доступа (исходников и/или прав их менять). Он может не иметь проверок на isInterrupted, а также перехватывать с помощью try…catch(Exception e) все возникшие исключения.

Никто не гарантирует, что нить можно остановить. Она может остановиться только сама.

Комментарии (6)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Anonymous #3613348 Уровень 39
7 января 2026
Почему в учебном примере while вне try, а в задачах внутри?
Mikhail K Уровень 100
22 марта 2022
task1627. В условии Метод run должен получать текущую нить с помощью статического метода Water.getCurrentThread() , из-за того, что метод в классе называется getThread(), валидатор не принимает решение. И зачем это условие нужно, если в этот метод возвращает текущий Thread, и используется только для того чтобы записать в boolean isCurrentThreadInterrupted значение Thread.currentThread().isInterrupted(). Сразу записать его туда и всё.
Зепп Бранниган Уровень 1 Moderator
25 марта 2022
Пришлите в ЛС Ваш код, пожалуйста. Передадим команде на проверку.
Mikhail K Уровень 100
26 марта 2022
Здесь речь о том,что в коде задачи, который дается по умолчанию, название метода getThread(), а в условии getCurrentThread(). Нужно отредактировать, наверное, чтобы было одинаково.
Адам Уровень 109
7 августа 2024
да перестань ныть, зашел в интеледж чекнул и все
Семён Уровень 69
6 апреля 2025
думаю, за 2 года он уже перестал ныть