Остановка потока

Поток останавливают кооперативно: один код выставляет запрос на прерывание, другой регулярно его замечает, освобождает ресурсы и завершает run().

final class Worker implements Runnable {
    private final BlockingQueue<Job> jobs;
 
    Worker(BlockingQueue<Job> jobs) {
        this.jobs = jobs;
    }
 
    @Override
    public void run() {
        try {
            while (!Thread.currentThread().isInterrupted()) {
                process(jobs.take());
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            closeResources();
        }
    }
}
 
Thread thread = new Thread(new Worker(queue));
thread.start();
thread.interrupt();

Семантика interrupt

  • interrupt() выставляет флаг запроса.
  • isInterrupted() читает его и не очищает.
  • Thread.interrupted() читает флаг текущего потока и очищает.
  • sleep, wait, join и многие блокирующие методы при прерывании бросают InterruptedException и очищают флаг.

Если метод не может завершиться и обязан пробросить обычный результат, он обычно восстанавливает флаг: Thread.currentThread().interrupt(). Если метод действительно обработал отмену и выходит из верхнего уровня run, восстановление менее важно, но делает причину завершения наблюдаемой.

Не всякая операция мгновенно реагирует на interrupt. Для закрытия сокета, канала или стороннего клиента может потребоваться их собственный API отмены.

Warning

Thread.stop() небезопасен: асинхронно бросает исключение и освобождает мониторы в произвольной точке, оставляя данные в промежуточном состоянии. suspend() и resume() тоже не использовать.

На собеседовании

  • Прерывание — команда на убийство? Нет, кооперативный запрос.
  • Почему нельзя молча проглатывать InterruptedException? Теряется сигнал отмены, вышестоящий код продолжает ждать.
  • Как восстановить флаг? Thread.currentThread().interrupt().
  • Что делает Thread.interrupted()? Читает и очищает флаг текущего потока.
  • Всегда ли interrupt разблокирует I/O? Нет, зависит от API.