如何解决调用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)
中的锁?
为了更好的上下文,我之所以这样问是因为,显然,在使用各种线程且没有未成功回答的情况下,出现了一个随机点,即两个线程在为同一个followerId
调用appendEntries,然后在{ {1}},这不应该发生,我怀疑是原因。
如果您需要进一步的说明,我正在为类项目实现共识算法Raft。如果您不熟悉它,那么基本上这段简化的代码就是“领导者”逻辑的一部分,他必须将日志中的条目发送给他的“跟随者”。领导者和跟随者的日志最终必须保持一致。这段代码在一个线程上,当“领导者”希望将其日志条目发送到特定的跟随者时,该线程将被调用,但是他对每个跟随者一次都不应多次调用reqs
方法。 appendEntries
是领导者为每个关注者知道的最后一个条目的位置。
我希望它不是太多或太少的信息,这是我使用该网站多年后的第一个堆栈溢出问题,我们将不胜感激。
解决方法
正如@NathanHughes指出的那样,我的问题是我在具有锁定的对象上使用了replace方法,并且弄乱了同步对象。我创建了一个新的对象数组,专门用于锁定,现在可以完美地工作了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。