Runtime.getRuntime()。exec(...)导致死锁

时间:2013-10-10 10:54:01

标签: java external exe deadlock

我们正在尝试使用Runtime.getRuntime().exec(...)在Windows中调用外部程序,但它似乎会导致死锁。外部进程是异步启动的,但过了一会儿就停止了做任何事情。 当我停止Java线程时,外部进程继续,因此它必须以某种方式等待Java线程。这是我们目前的相关代码:

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 个答案:

答案 0 :(得分:1)

终于找到了罪魁祸首。显然,运行时进程不仅提供输入流(Process#getInputStream),还提供错误流(Process#getErrorStream)。错误流也在填满,因为外部程序在文件格式错误方面存在一些错误。

解决方案包括创建一个新的runnable类,该类从一个单独的线程中的流中读取。然后,主线程将创建此对象的两个实例,一个将从输入流中读取,另一个将从错误流中读取,然后让两个实例异步运行其线程。这样两个流同时被读取,主线程将调用Process#waitFor

我希望这可以帮助那些偶然发现这个问题的人。

答案 1 :(得分:0)

  

Java程序正在等待外部程序完成   (process.waitFor()),外部程序直到我才完成   终止Java程序,从而导致死锁。我们怎么样   防止这种情况?

你无法阻止它。根据Java docs

  

如果   子进程尚未终止,调用线程将被阻塞   直到子进程退出。