Open fsan42 opened 1 year ago
方法级别加了synchronized
if (N > commitIndex) { LogEntry entry = logModule.read(N); if (entry != null && entry.getTerm() == currentTerm) { commitIndex = N; } } // 响应客户端(成功一半) if (success.get() >= (count / 2)) { // 更新 commitIndex = logEntry.getIndex(); // 应用到状态机 getStateMachine().apply(logEntry); lastApplied = commitIndex; log.info("success apply local state machine, logEntry info : {}", logEntry); // 返回成功. return ClientKVAck.ok(); } else { // 回滚已经提交的日志. logModule.removeOnStartIndex(logEntry.getIndex()); log.warn("fail apply local state machine, logEntry info : {}", logEntry); // TODO 不应用到状态机,但已经记录到日志中.由定时任务从重试队列取出,然后重复尝试,当达到条件时,应用到状态机. // 这里应该返回错误, 因为没有成功复制过半机器. return ClientKVAck.fail(); }
这种涉及到多线程操作的变量比如commitIndex 虽然是 volatile修饰了 但是是不是仍然存在线程安全问题可能被一个旧的更小的值覆盖掉?而这里的赋值有很多先查询后写入的过程,那如果这里有问题,我们继续推断一下,是不是所有多线程操作的变量都有可能出现更新丢失?
你最好将这块代码所在的 类#方法 说明白啊; DefaultNode#handlerClientRequest() 方法
这种涉及到多线程操作的变量比如commitIndex 虽然是 volatile修饰了 但是是不是仍然存在线程安全问题可能被一个旧的更小的值覆盖掉?而这里的赋值有很多先查询后写入的过程,那如果这里有问题,我们继续推断一下,是不是所有多线程操作的变量都有可能出现更新丢失?