Подтвердить что ты не робот

В чем разница между вызовом System.exit(0) и Thread.currentThread(). Interrupt() в основном потоке Java-программы?

Оба запускают выполнение программы. Ясно, что должны быть некоторые различия в том, как это происходит. Что они?

4b9b3361

Ответ 1

Резюме

  • thread.interrupt() не останавливает поток. Он используется для координации в многопоточных программах. Не используйте его, если вы точно не знаете, что делаете.
  • Throwing RuntimeException будет (обычно) завершать поток, но не обязательно программу.
  • System.exit(int) почти всегда завершает работу программы и возвращает код состояния.
  • В необычных ситуациях System.exit(int) может не остановить программу. Runtime.getRuntime().halt(int), с другой стороны, всегда делает.

Прерывание потока

Я боюсь, что ваше первое предложение ошибочно. Thread.currentThread().interrupt() не останавливает нить или программу.

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

В частности, прерывание потока (любой поток, включая текущий исполняемый) будет устанавливать только прерванный флаг. Некоторые методы в стандартной библиотеке будут вызывать InterruptedException, но это также является способом оповестить, что поток был прерван. То, что должно быть сделано в такой ситуации, - это код, выполняемый в этом потоке.

Вот соответствующие части из Java Concurrency в книге Практики Брайана Гетца:

Thread предоставляет метод прерывания для прерывания thread и для запроса, был ли поток прерываться. Каждый поток имеет логическое свойство, которое представляет его прерванный статус; прерывание наборов потоков этот статус.

Прерывание - это механизм сотрудничества. Один поток не может заставить другого остановить то, что он делает, и сделать что-то еще; когда поток А прерывает нить В, А просто требуя, чтобы B прекратил то, что он делает, когда он добирается до удобная точка остановки, если это похоже на это. Пока ничто в спецификации API или языка, которая требует любая конкретная семантика уровня приложения для прерывания, наиболее разумное использование для прерывания - это отмена активности. Методы блокировки, реагирующие на прерывание, делают это легче отменить длительные действия на своевременной основе.

Исключения и System.exit(int)

Javadoc System.exit(int) говорит:

Завершает работу текущей виртуальной машины Java. Аргумент служит в качестве кода состояния; по соглашению, ненулевой код состояния указывает на ненормальное завершение.

Таким образом, вызов exit() (почти) обязательно остановит вашу программу. В отличие от бросания RuntimeException (или Error), это невозможно поймать где-то в стеке вызовов, и это также не зависит от того, существуют ли другие потоки. С другой стороны, непокрытое исключение завершает поток, в котором он был брошен, но если есть какие-то другие (не-демонные) потоки, программа будет продолжать работать.

Еще одно отличие от исключения исключений заключается в том, что exit() ничего не будет печатать на консоли (как и неперехваченное исключение), но вместо этого программа возвращает конкретный код состояния. Коды статуса иногда используются в командах оболочки или пакетных сценариев, но кроме этого, они не очень полезны.

Runtime.halt(целое)

Наконец (для полноты), я хотел бы указать на третью возможность выхода из программы Java. Когда вызывается System.exit(int) (или программа заканчивается каким-то другим способом), среда выполнения выполняет некоторую работу по очистке до остановки виртуальной машины Java. Это описано в Javadoc Runtime.exit(int) (который вызывается System.exit(int):

Последовательность выключения виртуальной машины состоит из двух фаз. На первом этапе все зарегистрированные крючки остановки, если они есть, запускаются в определенном неуказанном порядке и разрешены для запуска одновременно до их завершения. На втором этапе все неинвинированные финализаторы запускаются, если включена опция финализация на выходе. Как только это будет сделано, виртуальная машина остановится.

Если какой-либо завершающий или финализатор не завершен, например, из-за deadlock, программа никогда не сможет выйти. Единственный метод, гарантирующий, что остановки JVM Runtime.halt(int):

Этот метод следует использовать с особой осторожностью. В отличие от метода выхода, этот метод не приводит к запуску задержек выключения и не запускает неинвинированные финализаторы, если включена опция finalization-on-exit.

Ответ 2

Если есть другие (не-демонные) потоки, JVM не выйдет, если вы остановите основной поток. System.exit() убивает все остальные потоки.

Ответ 3

В многопоточном приложении выполняется более одного потока. Thread.currentThread().interrupt() только прерывает текущий текущий поток, но оставшийся поток будет запущен, даже если ваш основной поток прерывается.

В то время как System.exit(0) приводит к завершению вашей системы.. И все потоки убиты..