从另一个java进程调用java使其停止

时间:2012-06-09 05:06:18

标签: java multithreading concurrency parallel-processing

我有一个带有2个进程java的程序:processA和processB(2进程java.exe不是2个线程)。 我使用进程A下面的代码块来调用processB,这段代码包含在

下面的RunTask类中
public class RunTask implements Callable<Object> {

private String runParams;

public String getRunParams() {
    return runParams;
}

public void setRunParams(String runParams) {
    this.runParams = runParams;
}

@Override
public Object call() throws Exception {
    try {
        //System.out.println("run:" + runParams);
        Process procB = Runtime.getRuntime().exec("java -jar processB.jar);
        DataInputStream ls_in = new DataInputStream(procB.getInputStream());
        String ls_str;
        while ((ls_str = ls_in.readLine()) != null) {
            System.out.println(ls_str);
        }

    } catch (Exception exp) {
        exp.printStackTrace();
    }
    return null;
}
}

和Main class我使用执行器

   ExecutorService eservice = Executors.newSingleThreadExecutor();
        while (1 == 1) {
            String stringParams = getFilesNeedToImportAsString();
            if (stringParams.trim().isEmpty()) {
                long l1 = System.currentTimeMillis() - l;
                System.out.println("all time" + l1 / 1000);
                System.exit(100);
            }
            RunTask runTask = new RunTask();
            runTask.setRunParams(SystemInfo.RUN_COMMAND + stringParams);
            Future<Object> objectFuture = eservice.submit(runTask);
            while (!objectFuture.isDone()) {
                System.out.println("waiting the task running");
                Thread.sleep(500);
            }
        }

但是当processB上发生异常时,两个进程(processA,processB)似乎都停止了,这就是在processB上运行的代码

public Object call() {
    try {
        MutationResult result = mutator.execute();
        return "ok";
    } catch (Exception exp) {
        exp.printStackTrace();
        System.out.println("error on " + Thread.currentThread().getName() + "failed begin retry " + (++retryCount));
        call();
        System.out.println(retryCount + " completed");
        return "ok";
    }

}

如果我单独运行processB(通过命令行)它永远不会发生,或者当发生此问题时我使用taskmanager来杀死proceesA(被调用者),processB继续运行

请任何人给我这个问题的解决方案!!

3 个答案:

答案 0 :(得分:2)

您等待objectFuture isDone方法完成。根据文件:

  

isDone:如果此任务完成,则返回true。完成可能是由于   正常终止,例外或取消 - 在所有这些中   例如,此方法将返回true

查看发生异常时processB中的代码,再次递归执行call()。我知道你这样做是一种错误重试机制,但这有两个主要原因,这是一个非常糟糕的主意: - 如果异常仍然存在,您最终会获得StackOverflowException。 - isDone的任何条件都不会得到满足。

更好的替代方案是定义最大重试次数并尝试执行mutator.execute()。如果错误仍然存​​在,则抛出异常并完成执行。

另一个选择是等待processB完成最长时间,然后通过调用objectFuture.cancel(true)取消执行任务。

关于processA的几条评论:在RunTask上,您不使用runParams,这些文件似乎是一些需要作为字符串导入的文件。此外,您在readLine()上使用DataInputStream这是一种弃用的方法。而是使用包裹在InputStream中的BufferedInputStream(例如InputStreamReader),然后将其包裹在BufferedReader中 - 然后在readLine()上调用BufferedReader

答案 1 :(得分:1)

我在生成exec时遇到的一件事就是,如果发生错误并且我没有设置线程来读取ErrorStream,那么ErrorStream缓冲区可以填满,此时所有内容都会变为停止等待我清除ErrorStream缓冲区中的一些文本。在我执行之前,进程B不能再写错误,并且进程A正在等待进程B完成。

我的经验的最终结果:当你执行exec()时,总是设置一个线程来读取每个InputStream和ErrorStream。

答案 2 :(得分:1)

printStackTrace将打印到标准错误,而不是标准错误。您还需要读取标准错误(这很棘手 - 您需要2个线程,每个流一个),或者打印到标准输出(printStackTrace(System.out))。