2009-06-22 3 views
19

Мне интересны разные подходы к изящному завершению программы командной строки Java. Отправка сигнала об уничтожении не является вариантом.Лучший способ изящно закрыть программу командной строки Java

Я могу придумать несколько разных подходов.

  1. Открыть порт и дождаться соединения. Когда он сделан, изящно выключается.
  2. Следите за созданием файла, затем выключением.
  3. Прочитайте некоторые данные с терминала, например, «выполнить выключение».

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

+0

Вы имеете в виду процесс, чтобы убить вашу программу командной строки java? – Tom

+2

Зачем посылать сигнал об убийстве не вариант? Как уже упоминалось в нижеприведенных ответах, вы можете захватывать и обрабатывать сигнал уничтожения с помощью крючков остановки. – toluju

ответ

2

Первые два варианта просты в реализации. Вы также можете использовать некоторые вещи JMX (я мало знаю об этом). Tomcat использует первый подход, и я применил 1 и 2 в двух моих проектах.

9

Вы можете попробовать использовать Runtime.getRuntime().addShutdownHook(), который должен удовлетворить ваши требования. Таким образом, вы можете зарегистрировать крючок для очистки, чтобы выполнить грациозное завершение работы.

EDIT

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread) общественная пустота addShutdownHook (крючок Thread) Регистрирует новую виртуальную машину-выключения крюка. Java-виртуальная машина выключается в ответ на два вида событий:

  • Программа выходит нормально, когда последние не-демон поток завершает работу или при выходе (что то же самое, System.exit) вызывается метод, или
  • Виртуальная машина завершается в ответ на прерывание пользователя, например, набирает^C или общесистемное событие, такое как выход пользователя из системы или выключение системы.
+0

Это не работает, когда выполняется cntrl + c. – 2009-06-22 18:25:37

+0

Но микрофон, его способ грациозно деградировать, если нажата клавиша ctrl + c, любая программа cmd будет завершена сигналом kill. –

+0

Ни один из других вариантов, о которых вы упомянули, не будет, так что поведение на ctrl + c, вероятно, не имеет отношения к решению одного из этих методов. – Herms

16

вы можете попробовать что-то вроде этого:

Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { /* 
     my shutdown code here 
    */ } 
}); 

редактировать:

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

из JavaDoc для Runtime (хорошо читать, если вы собираетесь использовать этот метод):

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

+0

Как это завершает его программу? –

+0

под редакцией. Я надеюсь, что вы ответите на свой вопрос. – akf

+0

Должен ли метод run иметь аннотацию @Override? –

5

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

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

+0

Вы можете ограничить входящие вызовы на основе IP-адреса клиента. Например, разрешить соединения только с localhost. Вы только выходите, когда это правильный IP-адрес, иначе закройте соединение и продолжите прослушивание нового. – akarnokd

+0

@ kd304 - Ограничение IP-адресов позволяет любому пользователю в локальной системе завершить процесс. Установив разрешения в каталоге, вы можете разрешить только конкретный пользовательский контроль процесса. –

0

Я бы предложил использовать крюк отключения. Это позволит контролировать вашу программу с помощью стандартных инструментов ОС. Он также не нуждается в дополнительном доступе к внешним ресурсам (диск, порты и т. Д.).

2

Если вы хотите пойти с версией сокета, его очень просто реализовать. Вот код:

ServerSocket server = new ServerSocket(8080); 
System.out.println("Socket listening!"); 
server.accept(); 
System.out.println("Connection received!"); 

Вы можете легко вставлять этот код в отдельном потоке, что вы начинаете с вашей программой, а затем его изменить глобальное состояние, чтобы инициировать отключение.

1

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

С помощью Java 6 u 10 или более поздней версии вы можете сделать то же самое с JVisualVM.

Смежные вопросы