В чем разница между 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()– только когда нужно сбросить флаг (например, перед повторной блокирующей операцией).