为什么ProcessBuilder需要更多时间来执行任务?

时间:2014-06-02 01:28:10

标签: java processbuilder

我直接从分析器程序对文件运行分析,并在一分钟内完成。但是,如果我制作jar分析器并通过ProcessBuilder运行它,即使在8分钟(500秒)内也无法完成。这是我用于ProcessBuilder的代码。有人可以解释原因吗?

我无法直接运行分析器程序,因为根据输入文件,实际上可能需要15-20分钟而我不想要。我想在8分钟内完成它。

以下是ProcessBuilder的代码。

public void myFun(){

    String fileName = file.getName();
    System.out.println(file.getAbsolutePath());

    Process p;
    ProcessBuilder pb;
    String filePath = file.getAbsolutePath();

        pb = new ProcessBuilder("C:\\Program Files\\Java\\jdk1.7.0_13\\bin\\java.exe", "-jar", "ta.jar", filePath);
        pb.directory(new File("D:\\Softwares\\analyzerRun\\bin"));

        long startTime = System.currentTimeMillis();

        try {
            p = pb.start();
            long currTime = System.currentTimeMillis();
            long diff = currTime - startTime;

            boolean isBreak = false;
            while(diff < 500000)
            {
                currTime = System.currentTimeMillis();
                diff = currTime - startTime;

                if(processIsTerminated(p))
                {
                    isBreak = true;
                    break;
                }
            }
            if(!isBreak)
            {
                System.out.println("Interrupting current thread!!");
                p.destroy();
                Thread.currentThread().interrupt();
            }
            else
            {
                System.out.println("process terminated peacefully");
            }
            System.out.println("Done with "+ fileName);
        } catch (IOException e) {
            e.printStackTrace();
        } 
    }
}

private static boolean processIsTerminated (Process process) {
    try {
        process.exitValue();
    } catch (IllegalThreadStateException itse) {
        return false;
    }
    return true;
}

EDIT1:

所以在给出建议后,我删除了while循环,我的try代码现在如下所示:

try {
    p = pb.start();
    p.waitFor();
}

有趣的是,我运行这个程序并且在5分钟内没有完成。但如果我直接运行我的分析仪,它会在30秒内完成。 ProcessBuilder没有从CPU获得足够的优先级吗?

3 个答案:

答案 0 :(得分:0)

你的投票循环很疯狂。

建议:

1)启动()你的过程

2)保存开始时间。

3)调用waitFor()来阻止,直到进程完成。

4)然后取三角洲。

您将获得 MUCH 更好的结果 - 诚实!

如果你绝对必须异步运行(如果你的app 在子进程运行时无法阻塞),那么为步骤1)创建一个新的Java线程... ... 4)

... IMHO

ALSO: 运行Windows性能监视器(或等效的操作系统)并在进程运行时监视I / O等待,CPU利用率等,以试图找出延迟可能来自何处。

但是你的轮询循环本身会引入过多的CPU利用率。不要这样做!

答案 1 :(得分:0)

因为您大部分时间都在浪费CPU进行无睡眠轮询,而不是:

(a)消耗过程的输出和错误流,然后是 (b)调用waitFor()。

答案 2 :(得分:0)

要回答这个问题,&#34;有趣的是,我运行这个程序并且在5分钟内没有完成。但如果我直接运行我的分析仪,它会在30秒内完成。 ProcessBuilder没有从CPU获得足够的优先级吗? &#34;

经过很长一段时间,我终于发现我在原始程序中在标准输出上写了两行。因此,当我使用jar运行ProcessBuilder文件时,我没有从标准输出中读取。这个过程被绞死,最终被主流线程杀死。我刚从原始程序中删除了这两行,现在两种方式都需要相同的时间。