2017-03-01 83 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錯誤。

相關問題