Если Quartz Scheduler умирает, как я могу остановить дочерние процессы Java, которые он запустил? - PullRequest
3 голосов
/ 25 февраля 2009

В настоящее время я использую Quartz Scheduler вместо Cron на нашей Windows Server Server Box. У меня есть два конкретных задания, которые нужно было запустить в новой виртуальной машине, поэтому я использую объект ProcessBuilder в Java 5 для получения объекта «Процесс». Проблема, с которой я сталкиваюсь, заключается в том, что, когда наша JVM Quartz Scheduler останавливается, 2 задания в отдельной JVM продолжают работать.

        Process process = Runtime.getRuntime().exec(command);
        try
        {
            while (true)
            {

                Thread thread1 = new Thread(new ReaderThread(process.getInputStream()));
                Thread thread2 = new Thread(new ReaderThread(process.getErrorStream()));

                thread1.start();
                thread2.start();

                thread1.join();
                thread2.join();

Есть ли способ убить эти потоки, когда родительская JVM, связанная с моим Quartz Scheduler, умирает? Даже если бы я знал, как вручную убить их из другого процесса, я мог бы понять, как это сделать с помощью Quartz.

Заранее спасибо

Ответы [ 2 ]

3 голосов
/ 25 февраля 2009

Если Quartz JVM завершается нормально, вы можете просто уничтожить процессы в блоке finally. Это может устранить необходимость в крюке отключения. Хук отключения может не работать при аварийном завершении JVM. Состояние Javadocs времени выполнения,

Если виртуальная машина прерывает работу, то нельзя гарантировать, будут ли запущены какие-либо перехватчики завершения работы.

Вот модифицированный код (я добавил время ожидания и вызов метода для ожидания завершения процесса)

    private static final long TIMEOUT_MS = 60000;
    Process process = Runtime.getRuntime().exec(command);
    try
    {
        while (true)
        {

            Thread thread1 = new Thread(new ReaderThread(process.getInputStream()));
            Thread thread2 = new Thread(new ReaderThread(process.getErrorStream()));

            thread1.start();
            thread2.start();

            process.waitFor();
            thread1.join(TIMEOUT_MS);
            thread2.join(TIMEOUT_MS);
            ...
        }
    } finally {
        process.destroy();
    }

В целом я обнаружил, что процессы, порожденные Java, неуклюжи и не очень устойчивы, как вы, вероятно, обнаружили, учитывая необходимость двух ReaderThreads. В частности, подпроцессы, которые замораживаются, могут быть трудно завершены изнутри Java. В качестве последнего средства вы можете использовать команду Windows " taskkill ", чтобы убрать процесс из командной строки или запланированной задачи:

taskkill / IM MySpawnedProcess.exe

2 голосов
/ 25 февраля 2009

Вы можете использовать отключающий крюк.

class ProcessKiller extends Thread {
  private Process process = null;
  public ProcessKiller(Process p) {
    this.process = p;
  }


  public void run() {
    try {
      p.destroy();
    } catch ( Throwable e ) {}
  }
}

Runtime.getRuntime().addShutdownHook( new ProcessKiller( process ));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...