Java启动子进程后如何定时检测其输出是否包含Success!标识
Java检测子进程输出的实现方案
前置修改:调整ProcessBuilder配置
你当前代码里的inheritIO()会把子进程的IO直接重定向到父进程的控制台,父进程无法读取子进程的输出,首先要去掉该配置,建议同时开启错误流合并,避免子进程因为缓冲区满被卡死:
String[] command = {"java", "-jar", jarPath}; Process childProcess = new ProcessBuilder() .redirectErrorStream(true) // 合并标准输出和错误流,避免缓冲区阻塞 .command(command) .start();
步骤1:异步读取子进程输出
流的读取是阻塞操作,必须单独开线程处理,读取过程中直接标记是否命中Success!:
// 用volatile修饰,保证多线程下的可见性 volatile boolean detectSuccess = false; // 启动单独线程读取子进程输出 new Thread(() -> { try (BufferedReader reader = new BufferedReader( new InputStreamReader(childProcess.getInputStream(), StandardCharsets.UTF_8))) { String line; while ((line = reader.readLine()) != null) { // 可选:需要同步打印子进程输出到父进程控制台可以加这行 System.out.println("[子进程输出] " + line); if ("Success!".equals(line.trim())) { detectSuccess = true; } } } catch (IOException e) { e.printStackTrace(); } }).start();
步骤2:实现周期检测逻辑
方案1:ScheduledExecutorService实现(推荐,更稳定灵活)
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); // 0延迟启动,每5秒执行一次检测 scheduler.scheduleAtFixedRate(() -> { if (detectSuccess) { System.out.println("已检测到Success!标识"); scheduler.shutdown(); // 后续业务逻辑写在这里 return; } // 子进程已经退出就直接结束检测 if (!childProcess.isAlive()) { System.out.println("子进程已退出,未检测到Success!"); scheduler.shutdown(); } }, 0, 5, TimeUnit.SECONDS);
方案2:简单循环实现(适合轻量场景)
while (true) { if (detectSuccess) { System.out.println("已检测到Success!标识"); break; } if (!childProcess.isAlive()) { System.out.println("子进程已退出,未检测到Success!"); break; } try { Thread.sleep(5000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } }
注意事项
- 如果
Success!不是单独占一行,可以把匹配逻辑修改为line.contains("Success!") - 不要在定时任务里直接调用
readLine(),该方法是阻塞的,会卡住定时任务 - 子进程运行结束后要手动关闭调度器,避免线程资源泄漏
内容的提问来源于stack exchange,提问作者Software Dev
相关产品推荐
相关产品推荐

