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