Ver Fonte

示例三:获取子进程执行的状态码

yangyi há 1 semana atrás
pai
commit
1a9d449001
1 ficheiros alterados com 51 adições e 0 exclusões
  1. 51 0
      src/main/java/space/anyi/process/ExecuteStatusExample.java

+ 51 - 0
src/main/java/space/anyi/process/ExecuteStatusExample.java

@@ -0,0 +1,51 @@
+package space.anyi.process;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 示例三:获取子进程执行的状态码(退出码)。
+ *
+ * 子进程为 src/main/resources/code/executeStatus/Main.java(睡眠 10 秒后退出)。
+ * 演示两种获取退出码的方式:
+ * 1. waitFor() 阻塞等待直到子进程退出,返回退出码;
+ * 2. waitFor(timeout, unit) 限时等待,超时未退出返回 false,配合 destroy() 销毁进程后取退出码。
+ */
+public class ExecuteStatusExample {
+    private static final Logger log = LoggerFactory.getLogger(ExecuteStatusExample.class);
+
+    public static void main(String[] args) throws IOException, InterruptedException {
+        File workDir = Paths.get(System.getProperty("user.dir"), "src", "main", "resources", "code", "executeStatus").toFile();
+        Jdk.compileFixture(workDir);
+
+        // 方式一:waitFor() 不带参数,一直阻塞到子进程结束,返回退出码(0 正常,非 0 异常)
+        log.info("== 方式一:waitFor() 阻塞等待 ==");
+        Process process = new ProcessBuilder(Jdk.java(), "-Dfile.encoding=UTF-8", "Main")
+                .directory(workDir)
+                .start();
+        int exitValue = process.waitFor();
+        log.info("阻塞等待退出码: {}", exitValue);
+
+        // 方式二:waitFor(timeout, unit) 限时等待,返回值是 boolean(超时时间内是否退出),不是退出码
+        // 子进程睡眠 10 秒,此处只等 2 秒,必然超时返回 false
+        log.info("== 方式二:waitFor(2, SECONDS) 限时等待 ==");
+        process = new ProcessBuilder(Jdk.java(), "-Dfile.encoding=UTF-8", "Main")
+                .directory(workDir)
+                .start();
+        boolean flag = process.waitFor(2, TimeUnit.SECONDS);
+        log.info("2 秒内是否退出: {}", flag);
+        if (!flag) {
+            // 超时后子进程仍存活,先 destroy() 发出终止信号,再阻塞等待它真正结束
+            log.info("超时未退出,destroy 销毁子进程后阻塞等待");
+            process.destroy();
+            process.waitFor();
+        }
+        // 进程已结束,此时才能读取退出码;被信号终止时通常为 143(SIGTERM)
+        log.info("销毁后退出码: {}", process.exitValue());
+    }
+}