Process.waitFor()一个线程

时间:2013-03-18 16:58:07

标签: java multithreading process processbuilder inputstreamreader

在运行外部脚本时,我想同时和单独读取此脚本的ErrorStream和OutputStream,然后进一步处理它们。因此,我为其中一个流启动Thread。不幸的是,Process似乎不会waitFor Thread被终止,而是在非线程流没有进一步输入后返回。

简而言之,这就是我在做的事情:

ProcessBuilder pb = new ProcessBuilder(script);  
final Process p = pb.start();  

new Thread(new Runnable() {  
  public void run() {
    BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
    ...read lines and process them...
  }
}).start();

BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
...read lines and process them...

int exitValue = p.waitFor();
p.getOutputStream().close();
return exitValue;

是否有可能waitFor Thread被终止?

2 个答案:

答案 0 :(得分:1)

这是执行您想要做的事情的一般代码。在这种情况下,既有输入又有输出:我将someFile传递给流程并将输出汇总到System.outFiles.copy()ByteStreams.copy()只是将InputStreamOutputStream挂钩的番石榴便捷方法。然后我们等待命令完成。

final Process pr = Runtime.getRuntime().exec(cmd);

new Thread() {
    public void run() {
        try (OutputStream stdin = pr.getOutputStream()) {
            Files.copy(someFile, stdin);
        } 
        catch (IOException e) { e.printStackTrace(); }
    }
}.start();

new Thread() {
    public void run() {
        try (InputStream stdout = pr.getInputStream()) {
            ByteStreams.copy(stdout, System.out);
        } 
        catch (IOException e) { e.printStackTrace(); }  
    }
}.start();              

int exitVal = pr.waitFor();
if( exitVal == 0 )
    System.out.println("Command succeeded!");
else    
    System.out.println("Exited with error code " + exitVal);

如果您使用 try-with-resources 块在Java 7之前运行,那么这是一个更详细的版本:

final Process pr = Runtime.getRuntime().exec(cmd);

new Thread() {
    public void run() {
        OutputStream stdin = null;
        try {
            Files.copy(someFile, stdin = pr.getOutputStream());
        } 
        catch (IOException e) { e.printStackTrace(); }
        finally {
            if( stdin != null ) {
                try { stdin.close(); } 
                catch (IOException e) { e.printStackTrace(); }
            }
        }               
    }
}.start();

new Thread() {
    public void run() {
        InputStream stdout = null;
        try {
            ByteStreams.copy(stdout = pr.getInputStream(), System.out);
        } 
        catch (IOException e) { e.printStackTrace(); }
        finally {
            if( stdout != null ) {
                try { stdout.close(); } 
                catch (IOException e) { e.printStackTrace(); }
            }
        }               
    }
}.start();              

int exitVal = pr.waitFor();
if( exitVal == 0 )
    System.out.println("Command succeeded!");
else    
    System.out.println("Exited with error code " + exitVal);

答案 1 :(得分:1)

您可以使用Thread.join(...)等待Thread完成。请注意,如果当前线程在您等待完成的线程之前收到中断,则调用将抛出InterruptedException