В приложении Swing это хорошо для вызова System.exit()
от потока? (например, на EDT?)
Вам не следует вызывать System.exit ()
, если вы можете помочь.
Лучший способ выйти из java-процесса - позволить всем потокам нормально завершиться. Это остановит виртуальную машину.
В вашем основном JFrame
вы должны setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE)
.
Затем вы можете вызвать frame.dispose ()
, чтобы закрыть JFrame
и выйти из EDT.
Нет ничего плохого в том, чтобы вызывать System.exit из любого потока, который вы хотите. Если позволить ему выйти «в обычном режиме», это не сработает на практике, потому что вы обнаружите, что приложение будет зависать, пока сборщик мусора собирает данные, прежде чем приложение завершится. Я написал множество приложений с графическим интерфейсом Swing, и нет ничего плохого в том, чтобы называть его. Это тоже не «грубо». Это способ Java.
System.exit ()
завершает не запущенные потоки, а саму виртуальную машину. Таким образом, его можно вызывать из любого потока, результат всегда один и тот же, и если виртуальная машина умирает, все возможные несогласованные состояния в потоках сразу перестают существовать.
Существуют правила Swing для нормального завершения потока EDT.
Самое главное - убедиться, что все кадры утилизированы. К сожалению, это может быть не так просто, если вы используете модальные диалоги без родителей, потому что Swing создаст невидимый родительский фрейм для таких диалогов.
В этом случае вы должны перечислить все фреймы (для этого можно использовать Frame.getFrames ()
) и явно dispose ()
их.
Конечно, вы должны убедиться, что ни один Thread
не активен (кроме демонов). Некоторые библиотеки и даже некоторые API из JDK создают потоки, не являющиеся демонами, которые вы должны закрыть самостоятельно.
Наконец, что наиболее важно, отказ от вызова System.exit () не будет работать в среде Java Web Start (см. этот вопрос SO , чтобы найти дополнительную информацию).
В заключение я бы посоветовал на самом деле вызвать System.exit ()
, потому что вы не всегда знаете, в какой среде будет запущено ваше приложение. Но я бы добавил к этому важный момент: убедитесь, что есть одна точка, из которой осуществляется выход. Вызов его из любого потока будет нормально.
Поскольку виртуальная машина завершается после вызова System.exit ()
, я не думаю, что это имеет какое-либо значение, из какого потока выполняется вызов.
Вы можете вызвать его из любого потока, но использовать его ИМХО довольно грубо. Виртуальная машина будет остановлена независимо от того, что еще запущено.
Я предпочитаю dispose ()
или просто закрыть (имея setDefaultCloseOperation (DISPOSE_ON_CLOSE)
) любое отображаемое окно (JFrame, JDialog, ...). Если запущены только потоки демона, виртуальная машина будет остановлена. Если есть какой-то живой поток, не являющийся демоном, JVM не завершится, и поток может завершить свою работу.
Поступая так, я всегда могу включить (части) одной программы в другую, не беспокоясь о том, что одна из них случайно завершит работу другой.
Очень мало ситуаций, когда действительно нужно "убить" JVM ...