Java ProcessBuilder.start()花费的时间比在终端

时间:2017-03-01 14:30:14

标签: java multithreading process clearcase

我有一个GUI,当用户单击按钮时,它会启动一个新线程(getFilesThread)。这个线程调用下面我的start()类实例的ClearCaseProcess方法(我的组织不允许我使用ClearCase Java API),当进程结束时,它会更新GUI

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()之间经过的时间比在终端上运行相同的ClearCase命令所用的时间要长得多(大约5分钟) 1.5分钟)。我怀疑我读取stdout和stderr的循环是罪魁祸首,因为即使我的print语句在NetBeans控制台中生成输出也很慢。我怎样才能加快速度呢?

1 个答案:

答案 0 :(得分:2)

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

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