我直接从分析器程序对文件运行分析,并在一分钟内完成。但是,如果我制作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获得足够的优先级吗?
答案 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
文件时,我没有从标准输出中读取。这个过程被绞死,最终被主流线程杀死。我刚从原始程序中删除了这两行,现在两种方式都需要相同的时间。