Commit 1e2e8666 authored by wanghao's avatar wanghao

1 机械臂 状态检查和指令完成之间存在竞态条件,影响界面显示 指令状态问题调整。

parent 4567dc04
...@@ -56,7 +56,8 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP ...@@ -56,7 +56,8 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
private IRobotArmCommandService robotArmCommandService; private IRobotArmCommandService robotArmCommandService;
@Resource @Resource
private ApplicationEventPublisher eventPublisher; // 新增事件发布器 private ApplicationEventPublisher eventPublisher; // 新增事件发布器
// 命令完成锁,用于确保命令完成时只有一个线程执行
private final Object completionLock = new Object();
// 使用原子引用,确保状态变更的原子性 // 使用原子引用,确保状态变更的原子性
private final AtomicReference<CommandState> commandState = new AtomicReference<>(CommandState.IDLE); private final AtomicReference<CommandState> commandState = new AtomicReference<>(CommandState.IDLE);
...@@ -228,33 +229,40 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP ...@@ -228,33 +229,40 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
} }
private void handleCompleteState() { private void handleCompleteState() {
// 原子地获取并清空当前指令ID // 只在完全空闲时处理
Long commandIdToComplete = currentCommandId; Long commandIdToComplete = currentCommandId;
if (commandIdToComplete != null) { if (commandIdToComplete != null) {
// 尝试将状态从 EXECUTING 转为 COMPLETING synchronized (completionLock) {
if (commandState.compareAndSet(CommandState.EXECUTING, CommandState.COMPLETING)) { // 再次检查,防止在获取锁期间状态已改变
try { if (commandIdToComplete.equals(currentCommandId) &&
// 完成指令 commandState.compareAndSet(CommandState.EXECUTING, CommandState.COMPLETING)) {
robotArmCommandService.completeCommand(commandIdToComplete); try {
log.info("指令完成: {}", commandIdToComplete); // 完成指令
robotArmCommandService.completeCommand(commandIdToComplete);
// 清空当前指令 log.info("指令完成: {}", commandIdToComplete);
currentCommandId = null;
// 清空当前指令
// 状态转为空闲 currentCommandId = null;
commandState.set(CommandState.IDLE);
// 状态转为空闲
// 处理待执行指令 commandState.set(CommandState.IDLE);
handleFullyIdleState();
} catch (Exception e) { // 处理待执行指令(这里也加锁确保顺序)
log.error("指令完成失败: {}", commandIdToComplete, e); synchronized (this) {
commandState.set(CommandState.ERROR); handleFullyIdleState();
}
} catch (Exception e) {
log.error("指令完成失败: {}", commandIdToComplete, e);
commandState.set(CommandState.ERROR);
}
} }
} }
} else { } else {
// 没有当前指令,直接处理待执行 // 没有当前指令,直接处理待执行
handleFullyIdleState(); synchronized (this) {
handleFullyIdleState();
}
} }
} }
......
...@@ -154,7 +154,7 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService ...@@ -154,7 +154,7 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
} }
private void sendCommand(RobotArmCommand command, String commandType) { private void sendCommand(RobotArmCommand command, String commandType) {
// 更新状态为执行中 // 更新状态为执行中
command.setStatus("2"); command.setStatus("2");
command.setStartExecutionTime(new Date()); command.setStartExecutionTime(new Date());
......
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