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

如何优雅地退出Java中的进程?,java,windows,multithreading,Java,Windows,Multithreading,我正在尝试制作一个Java程序,它将运行其他几个不相关的Java程序,特别是Minecraft服务器。 目前,我正在尝试解决如何优雅地结束java.lang.Process 这是我的产卵器程序的代码: 这是生成的程序的代码: 我要做的是运行我的产卵程序。然后,几秒钟后,我用Ctrl-C终止它。 我想看到的是我的程序输出“正在关闭”,然后是“结束”。我还想看到一个文件“test.txt”。 我实际上看到的只是“关闭”,没有“结束”或“test.txt” 我认为问题在于Process.destr

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

这是我的产卵器程序的代码:

这是生成的程序的代码:

我要做的是运行我的产卵程序。然后,几秒钟后,我用Ctrl-C终止它。 我想看到的是我的程序输出“正在关闭”,然后是“结束”。我还想看到一个文件“test.txt”。 我实际上看到的只是“关闭”,没有“结束”或“test.txt”

我认为问题在于Process.destroy()在不让关机挂钩运行的情况下强制结束了进程


是否有一种方法可以替代Process.destroy(),它将优雅地退出进程(即:好像我按下了Ctrl-C)?

您可能需要查看远程方法调用,并让您的生成进程要求子进程自行关闭,而不是让生成进程杀死子进程本身。

您不应该破坏一个工作进程,因为它可能会使整个操作系统处于不稳定状态(相信我,这会导致我们停机2小时,给我的公司造成10000美元的损失:() 您应该做的是,如@Kane所述,向所有子进程发送关闭请求,并等待它们全部完成(每个子进程在正常退出之前向主进程发送RMI通知)

类父进程{
Map finishSignals=新的ConcurrentHashMap();
公共无效启动进程(){
//启动子进程
//获取其ID
//并为其创建倒计时闩锁
添加(processId,新的倒计时锁存器(1));
}
公共无效关闭进程(processId){
//向进程ID发送RMI请求以关闭
}
//停止前从子进程发送的RMI请求
public void processFinishedNotification(processId){
finishSignals[processId]。倒计时()
}
public void waitForChildsToFinish(){
//此for循环将被阻止,直到所有子进程都发送了完成通知
用于(倒计时闩锁子FinishSignal:finishSignals){
childFinishSignal.wait();
}
}
}

使用Java执行这项任务是否有特别的理由,比如说一个shell脚本/批处理文件?@MarkPeters我希望最终让这个程序在一个特定的端口上侦听,并让一个PHP脚本连接到它,让程序在派生的进程上执行命令,我更愿意使用Java来完成这项任务ng else.So的可能重复,因为您对Java很熟悉,无论它是否适合此工作?Java没有非常丰富的流程管理支持。@AVD:完全不同。这个问题是关于从Java内部关闭外部流程,这个问题是关于在发送si时优雅地关闭来自外部进程的gnal。谢谢。我希望更多的是“进程。停止”类型的解决方案,但是哦,好吧。也谢谢你的代码。
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();
    }
  }
}