2013-10-10 80 views
3

我們正在試圖調用使用Runtime.getRuntime().exec(...)在Windows外部程序,但它似乎導致死鎖。外部進程異步啓動,但一段時間後停止執行任何操作。 當我停止Java線程,外部過程繼續,所以它必須以某種方式等待Java線程。這是我們目前的相關代碼:調用Runtime.getRuntime()。EXEC(...)導致死鎖

try { 
    Process process = Runtime.getRuntime().exec(System.getProperty("user.dir") + "program.exe"); 
    BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); //Read output of program from its buffer. 
    String line; 
    while((line = input.readLine()) != null) { 
     System.out.println(line); 
    } 
    process.waitFor(); 
} catch(IOException e) { 
    e.printStackTrace(); 
} catch(InterruptedException e) { 
    e.printStackTrace(); 
} 

程序在輸出3313個字節後停止。我們嘗試了清空緩衝區的各種方法,因爲這似乎有時會導致此問題。

Java程序正在等待外部程序完成(process.waitFor()),並且在我終止Java程序之前,外部程序纔會完成,從而導致死鎖。我們如何防止這一點?我們無法訪問外部程序的來源。

回答

2

終於找到了罪魁禍首。顯然,運行時進程不僅提供輸入流(Process#getInputStream),還提供錯誤流(Process#getErrorStream)。錯誤流也填滿了,因爲外部程序給出了關於文件格式錯誤的一些錯誤。

該溶液由製作新的可運行的類,從在單獨的線程一個流中讀取的。然後主線程會創建這個對象的兩個實例,一個將從輸入流中讀取,另一個從錯誤流中讀取,然後讓兩個實例異步運行它們的線程。通過這種方式,兩個流都被同時讀取,主線程將調用Process#waitFor

我希望這可以幫助別人誰在這個問題上絆倒也。

0

的Java程序是等待外部程序來完成 (process.waitFor()),和外部程序沒有完成,直到我 終止Java程序,因此造成了死鎖。我們如何 防止這種情況?

你不能阻止它。據Java的docs

如果 子進程尚未終止,調用線程將被阻塞 直到子退出。

相關問題