我正在使用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(緩沖)調用.代碼如下:
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,multithreading,channel,nonblocking,rxtx
來源: https://codeday.me/bug/20191006/1861802.html