Что верно про прерывание потока через interrupt()?
- Как корректно остановить фоновый поток и почему нельзя вызвать Thread.stop?
- Фоновая задача в потоке должна корректно останавливаться при выключении приложения. Как это сделать и почему нельзя просто вызвать Thread.stop?
interrupt() — просьба, а не приказ: выставляет флаг; блокирующие sleep, wait, join бросают InterruptedException и сбрасывают флаг. Поток проверяет флаг сам и завершается в безопасной точке. Thread.stop убран, потому что бросал исключение в случайном месте и оставлял данные испорченными.
- Поймал InterruptedException и не пробросил — восстанови флаг: Thread.currentThread().interrupt()
- Пустой catch превращает отмену в тишину
- Пулы: shutdown, shutdownNow (прерывает потоки), awaitTermination
А ещё Альтернатива для простого цикла — volatile boolean
Подробно
Почему нет принудительной остановки. Thread.stop бросал ThreadDeath в произвольной точке — например, посреди изменения структуры данных. Мониторы освобождались, а инварианты оставались нарушенными. Метод был устаревшим с Java 1.2, а в Java 20+ бросает UnsupportedOperationException.
Кооперативная отмена:
while (!Thread.currentThread().isInterrupted()) {
try {
process(queue.take());
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // восстановить флаг
break;
}
}
- работающий поток сам проверяет
isInterrupted(); - заблокированный в
sleep,wait,join,BlockingQueue.takeполучаетInterruptedException, при этом флаг сбрасывается; - поймав исключение, нужно завершиться или пробросить его, а если нельзя — восстановить флаг для вызывающего кода.
Блокирующий ввод-вывод на старых потоках прерывание не замечает — помогает закрытие ресурса или каналы NIO (InterruptibleChannel).
Остановка пула: shutdown() — не принимать новые задачи, дождаться текущих; shutdownNow() — прервать работающие; затем awaitTermination с таймаутом.
Что хотят услышать
- Кооперативная модель прерывания.
- Сброс флага при исключении и его восстановление.
- Почему Thread.stop опасен.
- Остановка пула.
Частые ошибки
- Пустой catch InterruptedException.
- Ожидать, что interrupt мгновенно остановит поток.
Проверьте себя
Несколько верных вариантов. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗interrupt() немедленно завершает поток, освобождая все захваченные им мониторы и выполняя его блоки finally
- ✓interrupt() не останавливает поток, а лишь выставляет флаг — отмена кооперативная
- ✓Если поток блокирован в sleep/wait/join, бросается InterruptedException и флаг при этом сбрасывается
- ✓Поймав InterruptedException и не пробросив его, нужно восстановить флаг вызовом Thread.currentThread().interrupt()
Что спросят дальше
- Почему Thread.stop() признан небезопасным?
- Как корректно завершить задачу в пуле потоков?
- Чем shutdown отличается от shutdownNow?
- Что произойдёт, если поток заблокирован на сокете и его прервать?
Разбор темы
- Потоки: создание, состояния и отмена
Thread и Runnable, стоимость платформенных потоков, состояния жизненного цикла, кооперативное прерывание и daemon-потоки.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.