2011-01-07 123 views
3

使用Java的ProcessBuilder我創建一個組子進程。我可以使用生成的Process對象中的waitFor()方法來等待該特定子對象退出。的Java,等待子進程退出

有沒有可能阻止,直到任何子退出,以UNIX wait()系統調用的方式?

回答

0

閱讀有關CountDownLatch

初始化CountDownLatch有 定的計數。在AWAIT方法方框 直到當前計數達到零 由於調用countDown() 方法,之後所有等待 線程被釋放和立即等待返回 任何 後續調用。這是一次性的 現象 - 重置計數不能爲 。如果您需要 重置計數的版本,請考慮使用一個 CyclicBarrier。

-2

你必須使用某種形式的IPC來實現這一目標。如果允許使用本機庫,並且如果您在UNIX/Linux平臺上工作,請嘗試使用相同的wait()系統調用,方法是編寫一個簡單的JNI包裝程序&從Java代碼中調用本機方法。

如果您無法使用本機IPC機制使用它您可以控制來自服務器的子進程退出,而客戶端連接/斷開/從服務器的TCP/IP服務器/客戶端機制。當沒有子連接時,您可以退出服務器程序!

+0

有沒有這樣的東西作爲一個簡單的JNI包裝。 :) – sjr 2011-01-07 06:40:26

+0

這裏使用JNI的概念似乎很明顯,也可以原諒我的無知,但我不知道「某種形式的IPC」是什麼,你的回答沒有任何通知我,即使是一個快速的谷歌也沒有,幫助。對不起,我並不是經常冷靜下來,但這並沒有讓我覺得有用。 – PeterT 2012-11-05 21:25:29

9

第一步是代表每個子所做的工作作爲Future,像這樣:

final ProcessBuilder builder = ...; 

// for each process you're going to launch 
FutureTask task = new FutureTask(new Callable<Integer>() { 
    @Override public Integer call() { 
    return builder.start().waitFor(); 
    } 
}; 

現在提交所有任務執行人:

ExecutorService executor = Executors.newCachedThreadPool(); 
for (FutureTask task : tasks) { 
    executor.submit(task); 
} 

// no more tasks are going to be submitted, this will let the executor clean up its threads 
executor.shutdown(); 

現在使用優秀的ExecutorCompletionService類:

ExecutorCompletionService service = new ExecutorCompletionService(executor); 
while (!executor.isTerminated()) { 
    Future<Integer> finishedFuture = service.take(); 
    System.out.println("Finishing process returned " + finishedFuture.get()); 
} 

此循環將迭代一次前夕完成任務後完成。 returnValue將是子進程的退出代碼。現在

,你不知道到底哪個進程已經完成。你可以改變Callable來代替返回Integer來返回Process,或者更好的代表你自己的一個類來表示進程的輸出。

哦,當然,如果你不在乎等待所有的任務,你可以叫take()一次。