2011-11-27 84 views
3

我正在嘗試製作一個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

你不應該毀掉一個工作過程,因爲它可能會得到整個操作系統進入不穩定狀態(相信我,這引起了我們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

2

您可能希望查看遠程方法調用,並讓您的spawner進程請求子進程關閉自己,而不是讓spawner進程自己終止子進程。

+0

+1對於RMI指針! – GETah