Search code examples
javamultithreadingrmithread-synchronizationraft

Does calling an RMI method free the synchronized lock?


I call a RMI method and it's inside a synchronized block. Something like this, where the method appendEntries is the RMI method being called:

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();    
        }
    }
}    

While this thread is waiting for the RMI method's answer, does it free the lock that's in matchIndex.get(followerId)?

For better context, I ask this because, apparently, with various threads being used and no unsuccessful answers, there comes a random point where two threads are calling appendEntries for the same followerId and then a common Entry in reqs, which shouldn't happen and I suspect that's the cause.

If you need further explanation, I'm implementing the consensus algorithm Raft for a class project. If you're not familiar with it, basically this simplified piece of code is part of the "Leader" logic and he has to send the entries that are in its log to his "Followers". The logs on the leader and on the followers have to be eventually consistent. This piece of code is on a thread that is called when the "Leader" wants to send its log entries to a specific follower, but he shouldn't call the appendEntries method more than once at a time for each follower. The matchIndex are the positions of the last entry that the leader knows of for each follower.

I hope it's not too much or too little information, it's my first Stack Overflow question after years of using this website and any help would be appreciated.


Solution

  • My problem, as @NathanHughes pointed out, was that I was using the replace method on the object that had the lock and it messed up the synchronized. I created a new array of objects specifically for the purposes of locking and it now works flawlessly.