Java competition, simple example, multi-threaded hash map not secure

Asked

Viewed 81 times

1

I’m using a hash map to assign the voto at the id of a voter. But the class has several threads operating on top of the method addVote(...) and getVoteCount(...) , and the result returned is always unconscious, although he gave used the version synchronized hash map, Can anyone explain why not this thread safe yet? Any suggestions on how I can fix

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class SimpleVoteCounter {
    private final Map<Integer, Integer> electionsResults = 
            Collections.synchronizedMap(new HashMap<>());

    protected void addVote(Integer id){
        Integer old = electionsResults.get(id);
        int value = (old == null) ? 1 : old + 1;
        electionsResults.put(id, value);
    }

    protected Integer getVoteCount(Integer id){
        return electionsResults.get(id);
    }
}

1 answer

1


You don’t need to sync the HashMap nor adopt ConcurrentHashMap. Just synchronize the methods that access it:

public class SimpleVoteCounter {
    private final Map<Integer, Integer> electionsResults = new HashMap<>();
    private final Object lock = new Object();

    protected void addVote(Integer id){
        synchronized(lock) {
            Integer old = electionsResults.get(id);
            int value = (old == null) ? 1 : old + 1;
            electionsResults.put(id, value);
        }
    }

    protected Integer getVoteCount(Integer id){
        synchronized(lock) {
            return electionsResults.get(id);
        }
    }
}

I adopted an object lock apart as a matter of preference, you can synchronize the method itself (protected synchronized void addVote()) or even synchronize on itself HashMap (synchronized(electionsResults) { ... }) which equals.

  • But can you tell why the Concurrenthashmap the way I implemented was not safe? I thought that was the function of the library

  • Ahhh got it, thank you very much!

  • 1

    It would be safe if the operations on it were atomic, despite multiple simultaneous accesses. How addVote() is not atomic, it is necessary to "atomize" the operation with the block synchronized. When you do this, the class already ends up being safe to manipulate the HashMap without risk of competition.

  • I tried as Voce suggested, but now I get a warning after running the code referring to an excessive number of synchronizations, which is decreasing performance, but the results are correct. I will also try with Concurrent Hashmap, must have some function that does this work, to compare the performance

  • There is something wrong with your code then. Post it to take a look. This excessive number of synchronizations I have never seen happen. If so, ask a new question.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.