修改定时任务取消的逻辑,如果已经在运行 则不删除map,也不取消计数。如果未运行,可以取消成功,则删除旧任务,删除技术

feasure
xce 2026-01-19 00:35:37 +08:00
parent ee21847741
commit 3774c4dc4d
1 changed files with 23 additions and 13 deletions

View File

@ -336,8 +336,9 @@ public class MqttMessageHandler implements SmartLifecycle {
} }
} }
// ========== 关键设备回执完全不写入Redis ========== if (suc && StringUtils.hasText(funcType) && funcValue != null && funcValue == 0) {
// 移除所有回执相关的Redis写入逻辑 cancelAutoOff(deviceId, funcType);
}
} }
} }
@ -496,9 +497,6 @@ public class MqttMessageHandler implements SmartLifecycle {
// 改造:多线程执行自动关闭任务 // 改造:多线程执行自动关闭任务
// 起个任务,固定多少秒-n秒【监听最新的设备状态如果还在运行】发送设备关的指令 // 起个任务,固定多少秒-n秒【监听最新的设备状态如果还在运行】发送设备关的指令
private void scheduleAutoOff(String deviceId, String funcType, int delaySeconds) { private void scheduleAutoOff(String deviceId, String funcType, int delaySeconds) {
if (!StringUtils.hasText(deviceId) || !StringUtils.hasText(funcType) || delaySeconds <= 0) {
return;
}
// ✅ 防御避免极端情况下线程池尚未初始化导致NPE // ✅ 防御避免极端情况下线程池尚未初始化导致NPE
if (autoOffExecutor == null) { if (autoOffExecutor == null) {
@ -508,14 +506,7 @@ public class MqttMessageHandler implements SmartLifecycle {
String taskKey = "autooff:" + deviceId + ":" + funcType; String taskKey = "autooff:" + deviceId + ":" + funcType;
// 同设备同功能只保留最后一次任务(先取消旧任务) cancelAutoOff(deviceId,funcType);
ScheduledFuture<?> oldFuture = autoOffFutureMap.remove(taskKey);
if (oldFuture != null) {
oldFuture.cancel(false);
log.debug("【自动关任务】取消旧任务:{}", taskKey);
// ✅ 旧任务被替换需要同步减少该设备的“未完成任务数”避免计数虚高导致hasAutoOffTask误判
decAutoOffCnt(deviceId);
}
// 使用多线程池提交任务 // 使用多线程池提交任务
ScheduledFuture<?> newFuture = autoOffExecutor.schedule(() -> { ScheduledFuture<?> newFuture = autoOffExecutor.schedule(() -> {
@ -1012,6 +1003,25 @@ public class MqttMessageHandler implements SmartLifecycle {
} }
} }
// 新增:收到“关”指令时,尝试取消对应自动关任务(优化:减少无意义任务执行;正确性仍以到点状态判断为准)
private void cancelAutoOff(String deviceId, String funcType) {
if (!StringUtils.hasText(deviceId) || !StringUtils.hasText(funcType)) {
return;
}
String taskKey = "autooff:" + deviceId + ":" + funcType;
// 同设备同功能只保留最后一次任务:只有旧任务还没开始时才替换
ScheduledFuture<?> oldFuture = autoOffFutureMap.get(taskKey);
if (oldFuture != null) {
// cancel=false 说明任务已开始/已完成,避免双执行:不再创建新任务
if (!oldFuture.cancel(false)) {
return;
}
// cancel成功旧任务不会跑了这时再remove并减计数
autoOffFutureMap.remove(taskKey, oldFuture);
decAutoOffCnt(deviceId);
}
}
/** /**
* *
*/ */