【发布时间】:2016-04-16 11:17:27
【问题描述】:
我正在使用 Java Executors.newWorkStealingPool(); 并行运行多个命令。由于其中一些任务预计会超时,因此我为它们添加了 2 秒的超时时间。
ProcessBuilder pb = new ProcessBuilder(cmd.split(" "));
Process p = null;
StringBuilder result = new StringBuilder();
try {
p = pb.start();
p.waitFor(2000, TimeUnit.MILLISECONDS);
BufferedReader errreader =
new BufferedReader(new InputStreamReader(p.getErrorStream()));
BufferedReader outreader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = outreader.readLine())!= null)
result.append(line + "\n");
while ((line = errreader.readLine())!= null)
result.append(line + "\n");
outreader.close();
errreader.close();
} catch (InterruptedException e) {
result.append("INTERRUPTED");
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
finally {
p.destroy();
}
....
return b; // b is boolean
提交任务是这样的
List<ImmutablePair> curJobs = new ArrayList<ImmutablePair>();
for (int i = 0; i < allMutants.size(); i++) {
String mutant = allMutants.get(i);
t = executor.submit(new mutTask(mutant));
ImmutablePair pair = new ImmutablePair(mutant, t);
curJobs.add(pair);
}
最后。我在以下循环中收集结果。
// data collection loop
for (int i = 0; i< curJobs.size(); i++) {
ImmutablePair p = curJobs.get(i);
String m= (String) p.getLeft();
System.out.println(m);
t = (Future<Boolean>) p.getRight();
try {
boolean res;
try {
res = t.get(2000L, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
res = true;
}
finally {
t.cancel(true);
}}
问题在于,超时似乎并没有像程序中定义的那样终止某些命令或进程。几分钟后,数据收集循环变得非常缓慢。 ps 的结果显示一些作业在指定的超时时间以上运行并保持 CPU 繁忙。我的配置是 CentOS 上的 JDK8。
【问题讨论】:
-
所以,从JavaDocs中,我们知道“如果需要,使当前线程等待,直到这个Process对象所代表的子进程已经终止,或者指定的等待时间过去了。”,这意味着该方法将在进程存在或指定时间过去时返回,因此这意味着该进程可能仍在运行。接下来,您然后读取进程输出的内容,这意味着,如果进程仍在破坏,它要么仍在处理输出,要么正在阻塞...通常我使用子
Thread来读取输入,当 @987654327 @return,停止这些线程 -
...然后销毁进程
-
谢谢。正如您所指出的,问题不是检查
p.waitFor(2000, TimeUnit.MILLISECONDS);的输出。
标签: java concurrency process command java.util.concurrent