You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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();
            }
        }
    }
}

关键修改说明

  1. 移除waitFor()调用:这个方法是用来等待子进程终止的,完全不符合长期交互的需求,直接删掉就能避免父进程挂起。
  2. 异步读取子进程输出:readLine()是阻塞调用,如果放在主线程,会出现"父进程等子进程输出,子进程等父进程输入"的死锁,用单独线程分开处理输入输出就能解决。
  3. 复用流资源:把输入输出流的初始化移到循环外,避免重复创建流导致的异常,同时在finally块统一关闭资源。
  4. 强制刷新输出流:子进程每次输出后调用flush(),确保内容立刻写入管道,父进程能及时读取到结果。

内容的提问来源于stack exchange,提问作者user8225131

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:10:30