jSerialComm关闭串口失败

456 阅读1分钟

1. 背景

当我们开发串口通信相关的应用时,通常需要通过串口的名称获取到串口的资源,然后收发消息,最后释放串口给其它应用。但是在部分情况下,serialPort.closePort();并不能释放端口,用SSCOM再进行端口打开还是提示占用。

2.SerialPort.getCommPort(portLinkName) 存在问题

由于网络上没有太多有用信息,在尝试了多处没有效果后,我开始将目标瞄准这个静态方法。发现这个静态方法中有这样的代码:

// Create the SerialPort object
SerialPort serialPort = new SerialPort();
serialPort.comPort = portDescriptor;
serialPort.friendlyName = "User-Specified Port";
serialPort.portDescription = "User-Specified Port";
return serialPort;

而且在setComPortParameters中调用了本地方法,然而它并没有写finalize

我就猜想它是否无法释放对应的系统资源?每次这样获取和设定时,是否都会导致系统增加对于对象的引用,然后无法释放资源?

3.解决方案

那每次创建这个对象时,必须用Map存起来,然后再次使用的时候,指向这个唯一的对象,不再通过SerialPort.getCommPort(portLinkName)来获取。

比如:

portIdToSerialPortMap.putIfAbsent(portInfoId, serialPort);

需要操作它的时候,从Map中拿:

portIdToSerialPortMap.get(portInfoId);

当我们调用serialPort.closePort();后,则从Map中移除:

portIdToSerialPortMap.remove(portId);

这样我们的SSCOM不再持续报端口占用了,我们顺利解决了此问题。

总结

这个错误告诉我们:在使用操作系统资源时,尤其是设备时,需要考虑到 Java 是否调用了 native 方法,如果有这种情况,则需要管理好每一次资源的申请和释放。