如何实现Java父进程与子进程的循环双向通信?
问题分析与解决方案
你的问题核心出在两个关键逻辑错误上:
- 父进程调用了
subprocess.waitFor(),这个方法会强制阻塞到子进程终止,子进程加循环后不会退出,父进程自然一直挂起。 - 子进程原本只处理一次输入就退出,导致第一次交互后流关闭;但直接加循环又会因为父进程的阻塞逻辑卡死。
修改后的子进程代码
让子进程持续监听输入,直到收到exit命令才终止:
import java.io.*; public class Subprocess { public static void main(String[] args) { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); try { String input; // 循环处理输入,直到收到exit指令 while ((input = reader.readLine()) != null) { if ("exit".equals(input)) { break; } System.out.println(input.toUpperCase()); // 强制刷新输出流,确保父进程能及时获取输出 System.out.flush(); } } catch (IOException ex) { ex.printStackTrace(); } } }
修改后的父进程代码
调整核心逻辑,避免阻塞并异步处理子进程输出:
import java.io.*; public class MainProcess { static BufferedReader scanner = new BufferedReader(new InputStreamReader(System.in)); public static void main(String[] args) { String s = ""; Process subprocess = null; BufferedWriter bw = null; try { subprocess = new ProcessBuilder("java", "Subprocess").start(); // 提前初始化子进程输入流,循环内复用 bw = new BufferedWriter(new OutputStreamWriter(subprocess.getOutputStream())); // 单独启动线程读取子进程输出,避免主线程阻塞死锁 new Thread(() -> { try (BufferedReader br = new BufferedReader(new InputStreamReader(subprocess.getInputStream()))) { String linea; while ((linea = br.readLine()) != null) { System.out.println(linea); } } catch (IOException e) { e.printStackTrace(); } }).start(); // 主循环处理用户输入 while (!"exit".equals(s)) { s = scanner.readLine(); bw.write(s + "\n"); // 用\n作为换行符,匹配readLine()的读取规则 bw.flush(); } } catch (IOException e) { throw new RuntimeException(e); } finally { // 程序退出时清理资源 try { if (bw != null) bw.close(); if (subprocess != null) subprocess.destroy(); scanner.close(); } catch (IOException e) { e.printStackTrace(); } } } }
关键修改说明
- 移除
waitFor()调用:这个方法是用来等待子进程终止的,完全不符合长期交互的需求,直接删掉就能避免父进程挂起。 - 异步读取子进程输出:
readLine()是阻塞调用,如果放在主线程,会出现"父进程等子进程输出,子进程等父进程输入"的死锁,用单独线程分开处理输入输出就能解决。 - 复用流资源:把输入输出流的初始化移到循环外,避免重复创建流导致的异常,同时在finally块统一关闭资源。
- 强制刷新输出流:子进程每次输出后调用
flush(),确保内容立刻写入管道,父进程能及时读取到结果。
内容的提问来源于stack exchange,提问作者user8225131
相关产品推荐
相关产品推荐

