【问题标题】:If Quartz Scheduler dies, how do I stop the child Java processes that it started?如果 Quartz Scheduler 死了,我如何停止它启动的子 Java 进程?
【发布时间】:2009-02-24 21:59:26
【问题描述】:

我目前在我们的 Windows 2003 Server Box 上使用 Quartz Scheduler 作为 Cron 的替代品。 我有两个需要在新 VM 中启动的特定作业,因此我使用 Java 5 中的 ProcessBuilder 对象来获取我的“Process”对象。 我遇到的问题是当我们的 Quartz Scheduler JVM 停止时,单独的 JVM 中的 2 个作业继续运行。

        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();

当与我的 Quartz Scheduler 关联的父 JVM 死掉时,有没有办法杀死这些线程?即使我知道一种从不同进程手动杀死它们的方法,我也可以通过 Quartz 弄清楚如何做到这一点。

提前谢谢你

【问题讨论】:

    标签: java multithreading process


    【解决方案1】:

    如果 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】:

      您可以使用关闭挂钩。

      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 ));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-16
        • 2011-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多