[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-kak-ostanovit-potok":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":20,"progress":21,"seo":22},261,"kak-ostanovit-potok",8,"mnogopotochnost","Многопоточность","🔀","Как остановить поток?","\u003C!-- grade: 4\u002F5 — подробный ответ, но можно улучшить структуру -->\n\nВ Java принят **кооперативный (уведомительный)** механизм остановки потоков. Принудительная остановка (`Thread.stop()`) считается устаревшей и опасной (см. следующий вопрос).\n\n### Способ 1: Thread.interrupt()\n\nОсновной рекомендуемый механизм. Метод `interrupt()` выставляет **флаг прерывания** у потока. Поток должен самостоятельно проверять этот флаг и реагировать.\n\n\u003Cdetails>\n\u003Csummary>Пример: остановка через interrupt()\u003C\u002Fsummary>\n\n```java\npublic class InterruptDemo implements Runnable {\n    @Override\n    public void run() {\n        while (!Thread.currentThread().isInterrupted()) {\n            \u002F\u002F Полезная работа\n            System.out.println(\"Работаю...\");\n            try {\n                Thread.sleep(1000);\n            } catch (InterruptedException e) {\n                \u002F\u002F sleep() сбрасывает флаг прерывания!\n                \u002F\u002F Нужно восстановить его или выйти из цикла\n                System.out.println(\"Получен сигнал прерывания\");\n                Thread.currentThread().interrupt(); \u002F\u002F Восстановить флаг\n                break; \u002F\u002F Или return\n            }\n        }\n        System.out.println(\"Поток завершён корректно\");\n    }\n\n    public static void main(String[] args) throws InterruptedException {\n        Thread worker = new Thread(new InterruptDemo());\n        worker.start();\n        Thread.sleep(3000);\n        worker.interrupt(); \u002F\u002F Уведомляем поток о необходимости остановки\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n**Как `interrupt()` взаимодействует с различными состояниями потока:**\n\n| Состояние потока | Что происходит при вызове `interrupt()` |\n|---|---|\n| `RUNNABLE` (выполняется) | Устанавливается флаг прерывания; поток должен проверить его сам |\n| `TIMED_WAITING` (`sleep()`, `wait(timeout)`) | Поток пробуждается, выбрасывается `InterruptedException`, **флаг сбрасывается** |\n| `WAITING` (`wait()`, `join()`) | Аналогично `TIMED_WAITING` |\n| `BLOCKED` (ожидание монитора) | Устанавливается флаг, но поток остаётся заблокированным до получения монитора |\n\n### Способ 2: собственный volatile-флаг\n\nАльтернативный подход -- объявить собственный флаг остановки:\n\n\u003Cdetails>\n\u003Csummary>Пример: остановка через volatile-флаг\u003C\u002Fsummary>\n\n```java\npublic class VolatileFlagDemo implements Runnable {\n    private volatile boolean stopped = false;\n\n    public void stop() {\n        stopped = true;\n    }\n\n    @Override\n    public void run() {\n        while (!stopped) {\n            \u002F\u002F Полезная работа\n            System.out.println(\"Работаю...\");\n        }\n        System.out.println(\"Поток завершён\");\n    }\n\n    public static void main(String[] args) throws InterruptedException {\n        VolatileFlagDemo task = new VolatileFlagDemo();\n        Thread worker = new Thread(task);\n        worker.start();\n        Thread.sleep(3000);\n        task.stop(); \u002F\u002F Устанавливаем флаг\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n**Недостатки volatile-флага по сравнению с `interrupt()`:**\n\n| Аспект | `interrupt()` | volatile-флаг |\n|---|---|---|\n| Пробуждение из `sleep()`\u002F`wait()` | **Да** (выбрасывается `InterruptedException`) | **Нет** (поток ждёт до конца) |\n| Поддержка в стандартных API | Да (все блокирующие методы реагируют) | Нет (только ваш код) |\n| Сложность реализации | Проще | Нужно следить за `volatile` |\n\n### Особый случай: блокировка на I\u002FO\n\nЕсли поток заблокирован на операции ввода-вывода (`InputStream.read()`, `Socket.accept()` и т.д.), `interrupt()` **не выведет** его из этого состояния. Решения:\n\n- **Для сетевого I\u002FO:** закрыть сокет из другого потока -- метод `read()` выбросит `SocketException`.\n- **Для файлового I\u002FO:** блокировка обычно кратковременная; можно дождаться завершения.\n- **Для NIO-каналов (`InterruptibleChannel`):** `interrupt()` закроет канал и выбросит `ClosedByInterruptException`.\n\n> **Аналогия из жизни.** `interrupt()` -- это вежливый стук в дверь: «Можешь завершить работу?» Поток решает сам -- открыть дверь сразу, доделать текущую задачу, или проигнорировать. `Thread.stop()` -- это выбивание двери: быстро, но можно повредить мебель (данные).\n\n> **На собеседовании.** Покажите, что знаете именно кооперативный подход: (1) вызвать `interrupt()` извне, (2) проверять `isInterrupted()` внутри потока, (3) правильно обрабатывать `InterruptedException` -- не глотать молча, а либо прокидывать дальше, либо восстанавливать флаг через `Thread.currentThread().interrupt()`. Также упомяните, что volatile-флаг -- допустимая альтернатива, но `interrupt()` предпочтительнее, так как может прервать `sleep()` и `wait()`.","","middle",[15,16,17,18,19],"остановка потока","isInterrupted","interrupt","Thread","concurrency",[],null,{"title":23,"description":24,"ogTitle":25,"ogDescription":26,"keywords":27,"schemaAnswer":32,"featuredSnippetReady":33},"Как остановить поток в Java — interrupt() и флаги — Gymterview","В Java принят уведомительный порядок остановки: interrupt() выставляет флаг, поток проверяет isInterrupted() и принимает решение. stop() — deprecated.","Как корректно остановить поток в Java","Метод interrupt() выставляет флаг прерывания. Поток проверяет isInterrupted() и решает — продолжить или завершиться. Thread.stop() deprecated.",[28,29,30,31],"остановить поток Java","Thread.interrupt Java","isInterrupted Java","остановка потока без stop","В Java принят уведомительный порядок остановки. Метод interrupt() выставляет внутренний флаг прерывания. Поток периодически проверяет его через isInterrupted() и принимает решение о завершении. interrupt() также выводит поток из sleep()\u002Fwait() с выбросом InterruptedException. Альтернатива — собственный volatile-флаг.",true]