|
|
@@ -9,43 +9,50 @@ import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
/**
|
|
|
- * 示例三:获取子进程执行的状态码(退出码)。
|
|
|
+ * 示例三:获取 Process 执行的状态码(退出码)。
|
|
|
*
|
|
|
+ * 两个案例点各用一个 method 演示:
|
|
|
+ * <ul>
|
|
|
+ * <li>blockingWaitFor() —— waitFor() 阻塞式等待,返回退出码</li>
|
|
|
+ * <li>timedWaitFor() —— waitFor(timeout, unit) 限时等待,超时后 destroy() 销毁进程</li>
|
|
|
+ * </ul>
|
|
|
* 子进程为 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);
|
|
|
+ private static final File WORK_DIR = Paths.get(System.getProperty("user.dir"),
|
|
|
+ "src", "main", "resources", "code", "executeStatus").toFile();
|
|
|
|
|
|
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);
|
|
|
+ Jdk.compileFixture(WORK_DIR);
|
|
|
+ blockingWaitFor();
|
|
|
+ timedWaitFor();
|
|
|
+ }
|
|
|
|
|
|
- // 方式一:waitFor() 不带参数,一直阻塞到子进程结束,返回退出码(0 正常,非 0 异常)
|
|
|
- log.info("== 方式一:waitFor() 阻塞等待 ==");
|
|
|
+ /** 案例点:waitFor() 阻塞式等待。一直阻塞到子进程结束,返回退出码(0 正常,非 0 异常) */
|
|
|
+ private static void blockingWaitFor() throws IOException, InterruptedException {
|
|
|
Process process = new ProcessBuilder(Jdk.java(), "-Dfile.encoding=UTF-8", "Main")
|
|
|
- .directory(workDir)
|
|
|
+ .directory(WORK_DIR)
|
|
|
.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)
|
|
|
+ /** 案例点:waitFor(timeout, unit) 限时等待。子进程睡眠 10 秒,此处只等 2 秒必然超时 */
|
|
|
+ private static void timedWaitFor() throws IOException, InterruptedException {
|
|
|
+ Process process = new ProcessBuilder(Jdk.java(), "-Dfile.encoding=UTF-8", "Main")
|
|
|
+ .directory(WORK_DIR)
|
|
|
.start();
|
|
|
+ // 返回值是 boolean(2 秒内是否退出),不是退出码
|
|
|
boolean flag = process.waitFor(2, TimeUnit.SECONDS);
|
|
|
log.info("2 秒内是否退出: {}", flag);
|
|
|
if (!flag) {
|
|
|
- // 超时后子进程仍存活,先 destroy() 发出终止信号,再阻塞等待它真正结束
|
|
|
+ // 超时后子进程仍存活:先 destroy() 发终止信号,再阻塞等待它真正结束
|
|
|
log.info("超时未退出,destroy 销毁子进程后阻塞等待");
|
|
|
process.destroy();
|
|
|
process.waitFor();
|
|
|
}
|
|
|
- // 进程已结束,此时才能读取退出码;被信号终止时通常为 143(SIGTERM)
|
|
|
+ // 进程已结束才能读取退出码;被信号终止时通常为 143(SIGTERM)
|
|
|
log.info("销毁后退出码: {}", process.exitValue());
|
|
|
}
|
|
|
}
|