2010-04-21 5 views
5

До сих пор я использовал свое приложение как самостоятельный продукт. Поэтому, когда пользователь нажал кнопку «Стоп», я позвонил System.exit(0);, и все было нормально.Как я могу безопасно закрыть свое программное обеспечение?

Теперь мое приложение будет называться (программным способом) из другой программы. Итак, я боюсь, что System.exit(0); убьет не только мой процесс, но и внешнее программное обеспечение, которое запустило мою программу.

Итак, что является правильным способом отключения моего приложения, если получен соответствующий запрос от внешнего программного обеспечения? Мое приложение является графическим приложением. Итак, я хочу закрыть окно, но я также хочу закрыть все процессы, выполняемые моей программой.

ДОБАВЛЕНО:

Чтобы быть более конкретным, я хочу, чтобы закрыть все темы от моей программы. Моя программа не запускает какой-либо процесс ОС или любую другую программу.

+0

@ Roman: by * "процессы, выполняемые моей программой" * Вы имеете в виду все потоки, на которых работает ваша Java-программа, или ваша программа породила, скажем, другие исполняемые файлы (Un * x shell процессы, .exe, other Java-программа, работающая в их виртуальной машине, что угодно)? – SyntaxT3rr0r

+0

@WizardOfOdds, я имею в виду «все потоки моей программы Java». – Roman

+1

Как ваша программа вызывается? Является ли какой-то метод его вызовом уже запущенной программой Java, так эффективно ли они становятся одной программой? Или другая программа делает системный вызов для запуска новой виртуальной машины Java с вашей программой? –

ответ

0

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

От Javadoc System.exit Завершает в настоящее время работает на Java Virtual Machine)

EDIT: Если вы хотите сделать некоторые очистке кода перед выключением, http://java.sun.com/j2se/1.4.2/docs/guide/lang/hook-design.html

+0

@stacker, вы имеете в виду, что 'System.exit (0)' будет закрывать все потоки, включая поток внешнего программного обеспечения (который запустил мою программу). – Roman

+1

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

2

Если нити вы запускаемые являются а затем вызов System.exit (0) приведет к их уничтожению. В некоторых случаях это может оставить ваше приложение в противоречивом состоянии. Представьте, что нить сохраняла файл, например.

Вы должны убедиться, что ваши потоки «счастливы», чтобы умереть, прежде чем звонить в System.exit.

Один метод, который вы можете использовать для этого, с длинными работающими потоками - отравление. Для этого вы отправляете потокам сообщение, что они теперь должны умереть изящно, т. Е. Сообщение с постом. После того, как все они умерли, безопасно вызвать System.exit (0), чтобы завершить поток обработки событий Swing.

Существует множество различных способов реализации отравления, вы можете просто установить глобальную переменную флага, которую потоки проверяют, чтобы убедиться, что они были отравлены, или вы можете использовать библиотеки потоков Threads Java 5. Посмотрите на эту Javadoc, например, и вы найдете ссылки на эту технику:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html

0

Существует на «один размер подходит всем» ответ на это, что это капля в замене для системы .exit, к сожалению.

Вам, как правило, необходимо установить какой-то флаг, который сигнализирует всем вашим потокам о том, что настало время для выхода, и убедитесь, что они регулярно проверяют этот флаг. Это позволит им очистить изящно, не останавливаясь внезапно, а также гарантирует, что эффекты ограничены вашими собственными компонентами. В этом случае основной поток вашего приложения также будет наблюдать за флагом, дождитесь завершения всех потоков типа «рабочий» и затем вернется полностью до стека до тех пор, пока не будет достигнута точка входа вашего приложения.

Этот вопрос не слишком отличается от устаревших методов Thread.stop (и т. Д.), Особенно в отношении замены System.exit на что-то более уважительное. В этом свете полезно использовать why is Thread.stop() deprecated page.

Выбрасывание исключения (пользовательское, называемое чем-то вроде ApplicationStopException), чтобы развернуть стопку основного потока - это не такая плохая идея; это не позволяет вам обрабатывать специальную логику по всему вашему коду и вместо этого позволяет «сообщению» распространяться на более высокие уровни, где они могут принимать любые действия, необходимые для выхода из вашей программы изящно.

0

Я рекомендую вам сделать отметку, чтобы остановить поток, чтобы поток знал, когда он должен остановиться. Для GUI и окна вы можете вызвать frame.dispose().

Для System.exit(), я думаю, что это не повлияет на вызывающего абонента, вы можете попробовать посмотреть, что представляет собой реальный эффект, но, как уже рекомендовали другие люди, не вызывайте его прямо так, просто дайте потокам остановить само по себе