Search code examples
java-8synchronized

Should I implement synchronization in multi-listener scenarios?


I have a class which has two different listener methods. One is for listening to different messages and another one is for listening to state updates.

@Override
public void receive(Message message) {
    if (message.getObject() instanceof Boolean) {
        membership.put(message.src(), message.getObject());
        log.info("Membership state updated: {}", membership);
    }
}

@Override
public void setState(InputStream input) throws Exception {
    System.out.println("setState() works");
    Map<Address, Boolean> state = Util.objectFromStream(new DataInputStream(input));
    synchronized (membership) {
        //membership.clear();
        membership.putAll(state);
    }
    log.info("Set new membership state: {}", membership);
}

I haven't added enough context because they are unnecessary for this question. Here membership is a HashMap which gets updated by both listener methods. receive() is heavily used however is less critical. But setState() is rarely used but highly critical.

My question is: should I use synchronization for both methods. In case if setState() is called by a thread (say A) while receive() is still in execution by another thread (say B), should I worry about race condition in this case.

I really don't want to add synchronized to receive because this would impact performance.

Any insight is really helpful. Thanks in advance.


Solution

  • If those methods, and any other that access the membership can be called by different threads concurrently you will face race conditions. And you need to take into account not only methods that update the map, but also the ones reading it.

    You can avoid using synchronized in all methods that write or read from the map, by using a ConcurrentHashMap, a highly optimized thread-safe version of HashMap.