有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java进程不会终止

我使用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


共 (1) 个答案

  1. # 1 楼答案

    正如@MadProgrammer所指出的,问题是在进程终止时读取/err缓冲区。要解决这个问题,需要检查p.waitFor(2000, TimeUnit.MILLISECONDS);的输出

        try {
            p = pb.start();
            boolean timeout = !p.waitFor(2000, TimeUnit.MILLISECONDS);
            if (!timeout){
                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 ...