Gymterview
middle

В чем разница между interrupted() и isInterrupted()?

Оба метода проверяют флаг прерывания потока, который устанавливается вызовом Thread.interrupt(). Ключевое различие – в побочных эффектах и в том, чей флаг проверяется.

Сравнение

Характеристика Thread.interrupted() thread.isInterrupted()
Тип метода Статический Экземплярный (instance)
Какой поток проверяет Всегда текущий поток (Thread.currentThread()) Любой поток (тот, на котором вызван метод)
Сбрасывает флаг Да – после вызова флаг устанавливается в false Нет – флаг не изменяется
Типичное использование Проверка «меня прервали?» внутри рабочего цикла Проверка «прерван ли другой поток?» из наблюдателя

Сигнатуры

Пример
// Статический — проверяет текущий поток, сбрасывает флаг
public static boolean interrupted();

// Экземплярный — проверяет конкретный поток, НЕ сбрасывает флаг
public boolean isInterrupted();

Пример поведения

Пример: разница между interrupted() и isInterrupted()
public class InterruptedVsIsInterrupted {
    public static void main(String[] args) throws InterruptedException {
        Thread worker = new Thread(() -> {
            // Прерываем поток
            Thread.currentThread().interrupt();

            // isInterrupted() — НЕ сбрасывает флаг
            System.out.println("isInterrupted(): "
                + Thread.currentThread().isInterrupted()); // true
            System.out.println("isInterrupted(): "
                + Thread.currentThread().isInterrupted()); // true (флаг на месте)

            // Thread.interrupted() — СБРАСЫВАЕТ флаг
            System.out.println("interrupted(): "
                + Thread.interrupted());                    // true
            System.out.println("interrupted(): "
                + Thread.interrupted());                    // false (флаг сброшен!)
        });

        worker.start();
        worker.join();

        // isInterrupted() можно вызвать на другом потоке
        Thread anotherWorker = new Thread(() -> {
            try { Thread.sleep(10000); } catch (InterruptedException e) { }
        });
        anotherWorker.start();
        anotherWorker.interrupt();
        // Проверяем флаг другого потока из main
        System.out.println("anotherWorker прерван: "
            + anotherWorker.isInterrupted());
        // Может быть true или false — зависит от таймингов
    }
}

Типичная ошибка

Распространённая ошибка – использование Thread.interrupted() вместо isInterrupted() в цикле:

Пример
// ОШИБКА: первая проверка сбросит флаг, и цикл никогда не завершится
while (!Thread.interrupted()) {
    doWork();
    if (Thread.interrupted()) { // Первая проверка уже сбросила флаг!
        cleanup();
        break;
    }
}

// ПРАВИЛЬНО: используйте isInterrupted() для проверки в цикле
while (!Thread.currentThread().isInterrupted()) {
    doWork();
}

Аналогия из жизни. Представьте записку «Тебя искали» на вашем столе. isInterrupted() – это посмотреть на записку, убедиться, что она есть, и оставить на месте. Thread.interrupted() – это посмотреть на записку и выбросить её. Второй раз посмотрите – записки уже нет.

На собеседовании. Три ключевых отличия: (1) interrupted() – статический, проверяет текущий поток; isInterrupted() – экземплярный, проверяет любой поток; (2) interrupted() сбрасывает флаг, isInterrupted() – нет; (3) для проверки в рабочем цикле используйте isInterrupted(), а interrupted() – только когда нужно сбросить флаг (например, перед повторной блокирующей операцией).