Я вызываю метод 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)
?
Для лучшего контекста я спрашиваю об этом, потому что, по-видимому, при использовании различных потоков и отсутствии неудачных ответов возникает случайная точка, когда два потока вызывают appendEntries для одного и того же followerId
, а затем общая запись в reqs
, чего не должно происходить и Подозреваю, что причина в этом.
Если вам нужны дополнительные пояснения, я реализую алгоритм консенсуса Raft для классового проекта. Если вы не знакомы с этим, в основном этот упрощенный фрагмент кода является частью логики Лидера, и он должен отправлять записи, которые есть в его журнале, своим Последователям. Журналы на лидере и на последователях должны быть в конечном счете непротиворечивыми. Этот фрагмент кода находится в потоке, который вызывается, когда Лидер хочет отправить свои записи журнала определенному ведомому, но он не должен вызывать метод appendEntries
более одного раза за раз для каждого ведомого. matchIndex
— это позиции последней записи, известные лидеру для каждого последователя.
Я надеюсь, что информации не слишком много и не слишком мало, это мой первый вопрос о переполнении стека после многих лет использования этого веб-сайта, и любая помощь будет оценена по достоинству.