如何优雅地退出Java中的进程?

问题描述:

我正在尝试制作一个Java程序,它将运行其他几个不相关的Java程序,特别是一个Minecraft服务器。 目前,我正在努力解决如何优雅地结束java.lang.Process。如何优雅地退出Java中的进程?

这是我的产卵的程序代码: http://dl.dropbox.com/u/26746878/SpawnerSource/Main.java.txt

这是被催生的程序代码: http://dl.dropbox.com/u/26746878/SpawnerSource/Tester.java.txt

我做的是我的运行程序产卵。然后,几秒钟后,我用Ctrl-C终止它。 我想看到的是我的节目输出“关闭”,然后是“结束”。我也想看到一个文件'test.txt'。 我实际看到的不仅是“关闭”,没有“结束”也不是“test.txt的”

我相信问题是Process.destroy()被强制结束进程没有让关闭挂钩运行。

是否有替代Process.destroy()会优雅地退出进程(即:如果我按Ctrl-C)?

+0

有特定理由使用Java来执行此任务,通过说一个shell脚本/批处理文件? –

+0

@MarkPeters我想最终有此程序监听特定的端口,并有一个PHP脚本控制并且让程序在生成的进程上执行命令,我宁愿使用Java来完成此任务。 – RunasSudo

+0

可能重复的[如何优雅地停止java进程?](http://stackoverflow.com/questions/191215/how-to-stop-java-process-gracefully) – adatapost

你不应该毁掉一个工作过程,因为它可能会得到整个操作系统进入不稳定状态(相信我,这引起了我们2小时的停机时间和成本10000 $来我公司:() 你应该做的,而不是作为@Kane提到,发送关机请求你的所有子进程,并等待,直到他们全部完成(每个孩子进程发送一个RMI通知回到主程序的权利之前正常退出)

class ParentProcess{ 
    Map<int, CountDownLatch> finishSignals = new ConcurrentHashMap<int, CountDownLatch>(); 
    public void startProcess(){ 
    // Start child process 
    // get its ID 
    // and create a count down latch for it 
    finishSignals.add(processId, new CountDownLatch(1)); 
    } 
    public void shutDownProcess(processId){ 
    // Send an RMI request to process ID to shutdown 
    } 
    // RMI request sent from child process before stopping 
    public void processFinishedNotification(processId){ 
    finishSignals[processId].countDown() 
    } 
    public void waitForChildsToFinish(){ 
    // This for loop will block until all child processes have sent a finish notification 
    for(CountDownLatch childFinishSignal : finishSignals){ 
     childFinishSignal.await(); 
    } 
    } 
} 
+0

谢谢。我希望获得更多'process.stop'类型的解决方案,但是很好。也感谢代码。 – RunasSudo

您可能希望查看远程方法调用,并让您的spawner进程请求子进程关闭自己,而不是让spawner进程自己终止子进程。

+0

+1对于RMI指针! – GETah