在Java中,可以在关闭后重新打开System.in

For*_*bie 5 java io console multithreading

我有一个多线程控制台应用程序,可以从两个不同的来源获取输入.一个是用户输入控制台,另一个是网络.我使用BufferedReader.readline()来获取用户和块的输入,这很好,除非我在等待时接收网络输入.在这种情况下,我需要通过取消readline()来取消阻止用户线程.

我认为取消它的最好方法是关闭System.in并使readline()抛出异常.在那之后,虽然我需要重新打开它.那可能吗?

Ste*_*n C 8

无法重新打开System.in,System.outSystem.err.底层本机流是连接到其他进程的文件描述符,或者是应用程序无法识别其身份的文件.关闭基础本机文件描述符后,无法重新打开它们.

我能建议的最好的是你InputStreamSystem.in对象创建一个包装类,并将包装器编码close()为无操作.或者可以将包装器设置为"关闭"状态,而不实际关闭包装流.

在您的特定用例中,这将无效,因为您"需要"解除阻止读取时阻塞的线程System.in.所以在你的情况下,你需要从中进行非阻塞输入System.in.例如,使用该available()方法测试是否有任何要从控制台读取的字符.(通常可以安全地假设,如果available()返回大于零的数字,您将能够读取整行.)

(它也可以使用a实现非阻塞读取Selector,但我认为不可能为对象获得"可选择的通道" System.in.)


请注意,这Thread.interrupt()将无效.根据javadocs,它只有在您从可中断频道阅读时才会起作用.

  • System.in不是可中断的通道,并且

  • 如果是,则记录的行为interrupt()是通道被中断关闭.