java - 调用 RMI 方法会释放同步锁吗?
问题描述
我调用了一个 RMI 方法,它在一个同步块内。像这样,方法appendEntries
是被调用的 RMI 方法:
public void run() {
synchronized(matchIndex.get(followerId)) {
ArrayList<Entry> reqs = new ArrayList<>();
for (int i = matchIndex.get(followerId) + 1; i <= log.lastIndex(); i++) {
reqs.add(log.get(i));
}
try {
answer = server.serverList.get(followerId).appendEntries(reqs);
if (answer.isSuccessful()) {
matchIndex.replace(followerId, matchIndex.get(followerId) + reqs.size());
} else {
System.out.println("Not Successfull.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
当这个线程正在等待 RMI 方法的回答时,它是否释放了其中的锁matchIndex.get(followerId)
?
为了更好的上下文,我问这个是因为,显然,在使用各种线程并且没有不成功的答案的情况下,出现了一个随机点,两个线程分别调用 appendEntriesfollowerId
和一个公共 Entry in reqs
,这不应该发生,我怀疑这就是原因。
如果您需要进一步解释,我正在为一个类项目实现共识算法 Raft。如果您不熟悉它,基本上这段简化的代码是“Leader”逻辑的一部分,他必须将其日志中的条目发送给他的“Followers”。领导者和追随者的日志必须最终保持一致。这段代码在一个线程上,当“Leader”想要将其日志条目发送给特定的追随者时调用,但他不应该appendEntries
为每个追随者一次多次调用该方法。这matchIndex
是领导者知道的每个追随者的最后一个条目的位置。
我希望这不是太多或太少的信息,这是我使用本网站多年后的第一个 Stack Overflow 问题,任何帮助将不胜感激。
解决方案
正如@NathanHughes 指出的那样,我的问题是我在拥有锁的对象上使用了 replace 方法,它弄乱了同步。我专门为锁定目的创建了一个新的对象数组,它现在可以完美运行。
推荐阅读
- javascript - 如何使历史日志存储在电子表格中?
- python-3.x - 使用 Python 3.7.0 和 pyodbc-4.0.28 运行 pyodbc hive 连接时输出不可读
- javascript - Firebase Firestore 未从集合中返回任何数据
- jquery - 为什么选项拒绝附加到选择元素?
- python - 如果日期等于日期否则
- sql - 为什么 oracle 优化器不消除这种情况?
- reactjs - 使用 Hooks 时在 onPress 之前调用反应按钮
- javascript - 如何在 SQL 数据库中保存列表组?
- python - 有人可以解释为什么我的代码不能正常工作吗?
- wpf - 如何修复 AvaloniaUI XAML 窗口定义中的“无法从命名空间解析类型”错误?