Остановка таймера извне jvm

#java

#java

Вопрос:

У меня есть длительная задача таймера. На самом деле это пакетный процесс, который будет продолжать цикл вечно и работать над своим материалом. Эта пакетная программа написана на Java. Теперь, как мне попросить его корректно завершить работу, если, например, мне нужно выполнить некоторое обслуживание? Извне JVM?

Я мог бы придумать несколько грязных способов, в конце каждого цикла метода run, чтобы он проверял наличие файла в некотором каталоге. Если он присутствует, он остановится. Или создайте запись базы данных с просьбой остановить его.

Есть ли другой лучший способ сделать это?

Комментарии:

1. файл конфигурации не кажется мне слишком грязным, но это зависит от того, кто должен это делать, технический специалист или ваш клиент?

2. Вы имеете в виду, что у вас запущена как Java-программа, так и пакет, и вы хотите остановить пакет при завершении работы Java-программы, например, из-за обслуживания? (иначе почему это было бы помечено тегом ‘Java’? ; ) Один из способов, который вы можете использовать, — это запустить вашу Java-программу с «магическим числом», и ваш пакетный файл в своем основном цикле проверяет, что Java-программа с соответствующим магическим числом все еще запущена (вы, конечно, сначала передаете магическое число в пакет). Другим способом было бы взять PID созданного вами пакета и отправить им сигнал при выходе.

3. @sethu: «грязный способ» пакетной проверки файла означает, что вам нужно будет создать файл (из вашей Java-программы, верно?). Обычно я использую «магическое число», которое однозначно идентифицирует этот конкретный запуск моей Java-программы. Таким образом, я ничего не «загрязняю» и ни с чем не связываюсь, и если Java-программа внезапно завершится, пакет также завершится корректно (потому что пакет должен заметить, что уникальная Java-программа, которая запустила пакет, больше не запущена). «Магическое число» — это просто случайная строка, передаваемая в качестве аргумента в программу Java, например java -jar ex.jar A093BC3F32D8712

4. @sethu: «нет, это буду я» <- но тогда почему этот вопрос даже помечен «Java»!? 🙂 Это сама программа Java, которую вы хотите остановить изящно? Или пакетные процессы, которые он порождает? Или оба?

5. @user988052 — Существует только одна Java-программа. Это то, что я называю «пакетной программой». Это в пакетной Java-программе, где таймер выполняется в бесконечном цикле. Как мне остановить эту Java-программу извне jvm?

Ответ №1:

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

Вот ссылки на MBeans:

http://download.oracle.com/javase/1.5.0/docs/guide/management/overview.html

http://en.wikipedia.org/wiki/Java_Management_Extensions

Комментарии:

1. 1 это выглядит как правильный способ, но, честно говоря, было бы сложно реализовать?

2. @stivlo. Если приложение использует spring, то это может быть не так сложно -> static.springsource.org/spring/docs/2.5.x/reference/jmx.html

3. Я не знаю sethu, но я использую Spring, я попробую это, когда закончу этот проект, над которым я работаю. Спасибо!

4. Проголосовал, потому что я знаю, что это правильный путь .. но на данный момент мне кажется, что это немного сложно. Сначала нужно понять, как его использовать. Пока я буду придерживаться подхода к созданию файлов, а затем переключусь на это позже, я думаю.. Огромное спасибо!

Ответ №2:

вы можете добавить перехват завершения работы, который будет выполняться при завершении процесса (через диспетчер задач) для полного завершения работы

 Runtime.getRunTime().addShutDownHook(new Thread(){
    public void run(){
        //do shutdown (interrupt threads and tell them to shut down)
    }
});
  

Комментарии:

1. 1. Однако в Linux это будет работать отлично, если судить по использованию терминов OP, например batch , я подозреваю, что он работает в Windows. И в Windows (по моему опыту), когда вы нажимаете Ctrl-C на консольную программу, она не запускает перехват завершения работы, а вместо этого просто убивает процесс.

Ответ №3:

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

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

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