在Java中并行化阻塞调用

时间:2011-07-11 15:15:24

标签: java parallel-processing blocking readline

我目前正在使用以下代码来运行进程并从我自己的程序中打印其输出。我的问题是我想做的不仅仅是打印输出。但是,由于正在执行的进程几乎不会将输出打印到控制台,因此几乎从不执行注释行,因为readLine()方法正在阻塞。

Process p = Runtime.getRuntime().exec(executablePath);
ProcessWatcher pw = new ProcessWatcher(p);
BufferedReader output = new BufferedReader(new InputStreamReader(p.getInputStream()));
while(!pw.isFinished()) {
    String line = output.readLine();
    if(line != null) {
        System.out.println(line);
    }
    // I want to do something in parallel here
}

如果我可以给readLine()调用某种超时,或者我可以在自己的Thread中运行它,我的问题就解决了。后者是首选,但前者是可以接受的。我的主要目的是保持代码简单。

是否有一种很好的,简单的方法来并行化阻塞调用,或者我是否需要创建一个为此实现Runnable的新类?

3 个答案:

答案 0 :(得分:5)

您可以使用。

包装代码
new Thread(new Runnable() { public void run() {
///put your code here
}}).start();

您不能执行非阻塞readLine或具有超时的readLine。在任何情况下,编写代码来处理非阻塞连接通常要复杂10倍。 ;)

答案 1 :(得分:1)

readLine()来电确实在阻止,但是ready()上的BufferedReader来电不是 - 所以你可以检查一下你的读者是否准备就绪(非阻塞通话),然后执行阅读 - 类似的东西:

Process p = Runtime.getRuntime().exec(executablePath);
ProcessWatcher pw = new ProcessWatcher(p);
BufferedReader output = new BufferedReader(new InputStreamReader(p.getInputStream()));
while(!pw.isFinished()) {
  if( output.ready() ) {
    String line = output.readLine();
    if(line != null) {
        System.out.println(line);
    }
  }
    // I want to do something in parallel here
}

这将允许您在进程运行时在while循环中执行其他操作。

答案 2 :(得分:0)

IMO,你最好把“过程”产生的东西放在一个单独的执行线程中,因为产生一个过程可能需要不确定的时间,更不用说过多的东西可能会出错。将所有这些东西捆绑在一个单独的逻辑单元中会更加清晰。