2017-03-01 170 views
2

我有一个GUI,当用户单击按钮时启动一个新线程(getFilesThread)。此线程调用下面我的ClearCaseProcess类的实例的start()方法(我的组织不会让我使用ClearCase Java API),并且当进程结束时,它会更新GUI。Java ProcessBuilder.start()花费的时间比在终端中执行的时间长得多

private static class ClearCaseProcess { 

private ArrayList<String> stdout = new ArrayList<>(); 
private ArrayList<String> stderr = new ArrayList<>(); 
private ProcessBuilder pb = null; 

public ClearCaseProcess(ArrayList<String> commands, String dir) throws IOException { 
    pb = new ProcessBuilder(commands); 
    pb.directory(new File(dir)); 
} 

public void start() throws IOException { 
    long minStart = System.nanoTime(); 

    Process process = pb.start(); 

    Thread sout = new Thread() { 
     @Override 
     public void run() { 
      BufferedReader out = new BufferedReader(
       new InputStreamReader(process.getInputStream())); 

      String outLine = ""; 

      try { 
       while ((outLine = out.readLine()) != null) { 
        stdout.add(outLine); 
        System.out.println(outLine); 
       } 
      } catch (IOException ex) { 
       System.err.println(ex.getMessage()); 
      } 
     } 

    }; 
    sout.start(); 

    Thread serr = new Thread() { 
     @Override 
     public void run() { 
      BufferedReader err = new BufferedReader(
       new InputStreamReader(process.getErrorStream())); 

      String errLine = ""; 

      try { 
       while ((errLine = err.readLine()) != null) { 
        stderr.add(errLine); 
        System.err.println(errLine); 
       } 
      } catch (IOException ex) { 
       System.err.println(ex.getMessage()); 
      } 
     } 
    }; 
    serr.start(); 

    try { 
     process.waitFor(); 
     long execTime = System.nanoTime() - minStart; 
     System.out.println("Process '" + description + "' took " + execTime); 
    } catch (InterruptedException ex) { 
     System.err.println(ex.getMessage()); 
    } 
} 

} 

getFiles()需要从四个不同的ClearCaseProcess ES收集数据。我计划在四个线程中同时运行这些。如上所示,每个线程都有两个相关的辅助线程,以消耗stdoutstderr。我假设这将比连续运行ClearCase四次更快。但是,现在我只测试一个ClearCase调用。

我的问题是,时间打电话Process.start()Process.waitFor()返回之间经过的(约5分钟),远远长于我的终端(约1.5分钟)上运行相同的ClearCase命令的时间已过。我怀疑循环读取stdout和stderr是罪魁祸首,因为即使我的打印语句在NetBeans控制台中产生输出也很慢。我如何加快速度?

+2

您是否尝试过在Netbeans之外运行Java应用程序? – RealSkeptic

+0

嗯,奇怪。假设你首先关心运行时...你有没有尝试**从这些流中读取任何东西?只需启动进程命令并测量执行时间? *证明*这些流给出了开销? – GhostCat

+0

@GhostCat,如果进程实际上将任何东西发送到它的输出和/或错误流中,那么它对于Java程序使用它是必需的,否则外部进程可能永远不会终止。 –

回答

2

对于我的具体情况,在IDE内部运行(不调试)会导致开销。

从控制台(java -jar myExecutable.jar)运行时,时间非常接近。
Noobish错误。

相关问题