InterruptedException: что вызывает это?
Существуют интересные вопросы и ответы, касающиеся Java InterruptedException, например, "Причина InterruptedException" и " Обработка InterruptedException в Java". Тем не менее, ни один из них не говорит мне о возможных источниках InterruptedException.
А как насчет сигналов ОС, таких как SIGTERM, SIGQUIT, SIGINT? Вызывает ли нажатие CTRL-C в командной строке InterruptedException? Что-то еще?
1 ответ
Ничто из перечисленного не производит InterruptedException
,
Единственное, что может прервать поток, это вызов Thread#interrupt()
, JLS относительно ясна по этому вопросу из раздела 17.2.3:
17.2.3 Прерывания
Прерывание действий происходит при вызове
Thread.interrupt
а также методы, определенные для его вызова по очереди, такие какThreadGroup.interrupt
,
Смотрите официальное руководство по прерываниям для получения дополнительной информации. В частности:
Поток отправляет прерывание, вызывая
interrupt
наThread
объект для потока, который будет прерван. Для правильной работы механизма прерываний прерванный поток должен поддерживать собственное прерывание....
Механизм прерывания реализован с использованием внутреннего флага, известного как статус прерывания. Вызов
Thread.interrupt
устанавливает этот флаг. Когда поток проверяет наличие прерывания, вызывая статический методThread.interrupted
статус прерывания очищается. НестатическийisInterrupted
Метод, который используется одним потоком для запроса статуса прерывания другого, не изменяет флаг состояния прерывания.По соглашению, любой метод, который выходит, бросая
InterruptedException
очищает состояние прерывания, когда это происходит. Тем не менее, всегда возможно, что статус прерывания будет немедленно установлен снова другим вызывающим потоком.interrupt
,
Подразумевается, что это явный флаг, устанавливаемый только путем вызова interrupt()
, а не вызваны другими неизвестными внешними событиями. Это также подразумевается описанием исключения в различных методах, которые его генерируют, например (выделено мной):
InterruptedException
- если какой-либо поток прервал текущий поток. Прерванное состояние текущего потока очищается при возникновении этого исключения.
Цель системы прерываний в целом состоит в том, чтобы предоставить общую, четко определенную структуру, позволяющую потокам прерывать задачи (потенциально трудоемкие) в других потоках. Хотя вы могли бы реализовать аналогичную функциональность с явной логикой в своем собственном приложении, наличие этого четко определенного механизма позволяет независимым классам (например, JDK, другому стороннему коду, другим независимым классам в вашем собственном коде) предоставлять эту функциональность согласованным способом,
Много замечаний и "предупреждений", которые вы видите об обработке InterruptedException
не подразумевают, что их можно бросать совершенно спонтанно, они предназначены для поощрения хорошо спроектированных объектов, которые можно использовать в контекстах, которые еще не известны, где interrupt()
будет работать (так что вы действительно хотите предположить, что они могут генерироваться самопроизвольно, если вы создаете многократно используемые объекты, которые будут устойчивыми в будущих ситуациях - т.е. вы никогда не гарантируете, что ваш код когда-нибудь не будет использован кто-то, кто ожидает прерываний на работу).
Для быстрых одноразовых проектов вам не нужно беспокоиться об особой обработке этих исключений, если вы точно знаете, что не звоните interrupt()
и не звонят то, что может позвонить interrupt()
, но помните о последствиях этого в долгосрочной перспективе, особенно если вы в конечном итоге будете использовать этот код в других контекстах.