我正在使用 RXTX 从串口读取数据。读取是在以下列方式生成的线程中完成的:
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(port);
CommPort comm = portIdentifier.open("Whatever", 2000);
SerialPort serial = (SerialPort)comm;
...settings
Thread t = new Thread(new SerialReader(serial.getInputStream()));
t.start();
SerialReader 类实现了 Runnable 并且只是无限循环,从端口读取并将数据构造成有用的包,然后再将其发送到其他应用程序。但是,我已将其简化为以下内容:
public void run() {
ReadableByteChannel byteChan = Channels.newChannel(in); //in = InputStream passed to SerialReader
ByteBuffer buffer = ByteBuffer.allocate(100);
while (true) {
try {
byteChan.read(buffer);
} catch (Exception e) {
System.out.println(e);
}
}
}
当用户单击停止按钮时,将触发以下功能,理论上应该关闭输入流并脱离阻塞的 byteChan.read(buffer) 调用。代码如下:
public void stop() {
t.interrupt();
serial.close();
}
但是,当我运行这段代码时,我从来没有得到 ClosedByInterruptException,它应该在输入流关闭时触发。此外,执行会阻塞对 serial.close() 的调用——因为底层输入流仍会阻塞读取调用。我已经尝试用 byteChan.close() 替换中断调用,这应该会导致 AsynchronousCloseException,但是,我得到了相同的结果。
如能就我遗漏的内容提供任何帮助,我们将不胜感激。
最佳答案
您不能将不支持可中断 I/O 的流简单地包装到 InterruptibleChannel
中(而且,无论如何,ReadableByteChannel
不会扩展InterruptibleChannel
).
你得看看底层InputStream
的契约。 SerialPort.getInputStream()
对其结果的可中断性有何看法?如果它什么也没说,您应该假设它忽略了中断。
对于任何不明确支持可中断性的 I/O,唯一的选择通常是从另一个线程关闭流。这可能会在调用流时阻塞的线程中立即引发 IOException
(尽管它可能不是 AsynchronousCloseException
)。
然而,即使这也非常依赖于 InputStream
的实现——底层操作系统也可能是一个因素。
注意 newChannel()
返回的 ReadableByteChannelImpl
类的源代码注释:
private static class ReadableByteChannelImpl
extends AbstractInterruptibleChannel // Not really interruptible
implements ReadableByteChannel
{
InputStream in;
⋮
关于java - 线程中断未结束对输入流读取的阻塞调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3843363/