Commit b3f5ae6d authored by wanghao's avatar wanghao

Revert "1 测试 上电后通信 和 最终完成 定时任务功能"

parent 24862782
......@@ -221,35 +221,44 @@ public class DeviceStatusReaderAndTimeSetter {
}
}
/**
* 启动多设备监控(新增portTimeout参数,统一超时)
* 启动多设备监控(核心方法:修正threadMaster调用)
* @param ip 设备IP
* @param port 端口(501/502/503)
* @param deviceIds 设备ID列表
* @param resultHandler 结果处理器
* @param stopCondition 停止条件
* @param portTimeout 端口总超时(秒)
*/
public void startMultiDeviceMonitoring(
String ip, int port, List<Integer> deviceIds,
Consumer<DeviceStatusReaderDto> resultHandler,
Predicate<int[]> stopCondition,
int portTimeout) { // 单个端口总超时(秒)
int portTimeout) {
if (deviceIds == null || deviceIds.isEmpty()) {
log.warn("设备ID列表为空,不执行监控:IP={}, 端口={}", ip, port);
return;
}
final CountDownLatch latch = new CountDownLatch(deviceIds.size());
log.debug("启动端口{}监控:IP={},设备数={},超时={}s", ip, port, deviceIds.size(), portTimeout);
log.info("启动端口{}监控:IP={},设备数={},超时={}s", port, ip, deviceIds.size(), portTimeout);
for (int deviceId : deviceIds) {
final int devId = deviceId;
deviceExecutor.submit(() -> {
AtomicReference<ModbusMaster> threadMaster = null;
// 关键:threadMaster声明为普通ModbusMaster,无需包装
final ModbusMaster[] threadMaster = {null};
ExecutorService devExecutor = null; // 临时线程池,避免泄漏
try {
// 单个设备任务超时控制(portTimeout/设备数,避免整体超时
// 单个设备超时(端口总超时/设备数,确保不超总时间
int devTimeout = Math.max(1, portTimeout * 1000 / deviceIds.size());
ExecutorService devExecutor = Executors.newSingleThreadExecutor();
// 创建临时线程池(处理单个设备超时)
devExecutor = Executors.newSingleThreadExecutor();
Future<?> devFuture = devExecutor.submit(() -> {
try {
// 1. 创建独立连接(每个设备一个,避免复用泄漏
threadMaster.set(createModbusMaster(ip, port));
// 2. 读取数据(带重试
int[] result = readWithConditionalRetry(threadMaster.get(), ip, port, devId, stopCondition);
// 1. 创建独立连接(直接赋值,无需get()
threadMaster[0] = createModbusMaster(ip, port);
// 2. 读取数据(直接传threadMaster,无需get()
int[] result = readWithConditionalRetry(threadMaster[0], ip, port, devId, stopCondition);
// 3. 回调结果
if (resultHandler != null) {
resultHandler.accept(new DeviceStatusReaderDto(ip, port, devId, result));
......@@ -259,10 +268,8 @@ public class DeviceStatusReaderAndTimeSetter {
}
});
// 单个设备任务超时等待
// 单个设备超时等待
devFuture.get(devTimeout, TimeUnit.MILLISECONDS);
devExecutor.shutdown();
} catch (TimeoutException e) {
String errMsg = "设备" + devId + "超时:IP=" + ip + ", 端口=" + port;
log.error(errMsg, e);
......@@ -272,8 +279,13 @@ public class DeviceStatusReaderAndTimeSetter {
log.error(errMsg, e);
recordAlarm("03", "ip:" + ip + ",port:" + port + ",deviceId:" + devId, errMsg + ":" + e.getMessage());
} finally {
// 强制释放资源(无论成功/失败)
destroyModbusMaster(threadMaster.get(), devId);
// 1. 销毁Modbus连接(直接传threadMaster,无需get())
destroyModbusMaster(threadMaster[0], devId);
// 2. 关闭临时线程池(避免资源泄漏)
if (devExecutor != null && !devExecutor.isShutdown()) {
devExecutor.shutdownNow();
}
// 3. 计数减1
latch.countDown();
log.debug("设备{}完成:IP={}, 端口={},剩余任务={}", devId, ip, port, latch.getCount());
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment