Java IO inputstream在读取标准输出时阻塞&;外部C程序的标准错误

Java IO inputstream在读取标准输出时阻塞&;外部C程序的标准错误,java,java-io,Java,Java Io,几天前我在这里发布了相同的问题(),我在阅读时发现了一些很好的建议(while(is.read())!=-1)),但我仍然无法解决这个问题 在阅读了这个类似问题的答案之后 (尤指古斯发布的答案) 我开始相信使用is.read()循环输入流-如果程序是交互式的,则条件1不起作用(即它从用户处获取多个输入,并在后续输入时提供额外的输出,并且程序仅在给出显式退出命令时退出)。我承认我对多线程知之甚少,但我认为我需要一种机制,在需要用户输入时立即暂停输入流线程(stdout、stderr各一个),并在

几天前我在这里发布了相同的问题(),我在阅读时发现了一些很好的建议(while(is.read())!=-1)),但我仍然无法解决这个问题

在阅读了这个类似问题的答案之后

(尤指古斯发布的答案)

我开始相信使用is.read()循环输入流-如果程序是交互式的,则条件1不起作用(即它从用户处获取多个输入,并在后续输入时提供额外的输出,并且程序仅在给出显式退出命令时退出)。我承认我对多线程知之甚少,但我认为我需要一种机制,在需要用户输入时立即暂停输入流线程(stdout、stderr各一个),并在提供输入后恢复,以防止阻塞。以下是我的当前代码,该代码在指示行上遇到阻塞:

EGMProcess egm=new EGMProcess(新字符串[]{directory+“/egm”,“-o”, “CasinoA”、“-v”、“VendorA”、“-s”、“localhost:8080/gls/MessageRobot.action”, “-E”、“glss_环境认证中心”、“-S”、“glss_信号认证中心”、“-C”、“glsc_信号认证中心”, “-d”、“config”、“-L”、“config/log.txt”、“-H”、“GLSA SampleHost”},新字符串[]{“PATH=${PATH}”,目录)

egm.execute();
BufferedReader stdout=新的BufferedReader(新的InputStreamReader(egm.getInputStream());
BufferedReader stderr=新的BufferedReader(新的InputStreamReader(egm.getErrorStream());
EGMStreamgObjbler stdoutprocessor=新的EGMStreamgObjbler(stdout,egm);
EGMStreamGobbler标准处理器=新的EGMStreamGobbler(标准处理器,egm);
BufferedWriter stdin=新的BufferedWriter(新的OutputStreamWriter(egm.getOutputStream());
stderProcessor.run()// 而不是

Thread errThread = new Thread(stderrprocessor);
errThread.setDaemon( true );
errThread.start();

Thread outThread = new Thread(stdoutprocessor);
outThread.setDaemon( true );
outThread.start();
run()
只是
Runnable
中指定的方法
Thread.start()
在新的
Thread
中调用
Runnable
上的
run()

  • 如果只对runnable调用#run(),它将不会并行执行。要并行运行它,必须生成一个java.lang.Thread,该线程执行Runnable的#run()
  • 流是否阻塞取决于流的两侧。如果发送方未发送任何数据或接收方未接收数据,则存在阻塞情况。如果处理器必须在流被阻塞时执行某些操作,则需要在处理器内生成(另一个)线程,以等待新数据并在新数据流传输时中断备用进程

  • 首先,您需要了解线程和Runnable。您不直接调用Runnable.run(),而是设置线程来执行此操作,然后启动线程

    但更重要的是,三个独立线程的存在意味着需要一些仔细的设计。为什么是三线?你刚开始的两个,还有主要的一个

    我假设你的应用程序的总体想法是等待一些输出到达,解释它,并因此向你控制的应用程序发送一个命令

    因此,您的主线程需要等待其中一个读者线程说“啊哈!这很有趣,最好问问用户他想做什么。”

    换句话说,读者和作者之间需要某种沟通机制。
    这可以使用Java的事件机制实现。恐怕还有更多的阅读。

    这不是创建nio的原因吗

    我对nio中的频道了解不多,但可能会有所帮助。它展示了如何使用nio读取文件。可能有用

    stderrprocessor.run(); //<-- the block occurs here!
    stdoutprocessor.run();
    
    Thread errThread = new Thread(stderrprocessor);
    errThread.setDaemon( true );
    errThread.start();
    
    Thread outThread = new Thread(stdoutprocessor);
    outThread.setDaemon( true );
    outThread.start();