Search code examples
javamultithreadingconcurrencymessage-queueconcurrenthashmap

how to concurrently put an element (might exist) without lock in ConcurrentHashMap?


I'm writing a simple message queue program and I have multiple producers and multiple serializer (consumer is not considered right now). The producer specifies which queue it want to send message to by using a String queueName. And the serializer could only be initialized during sending procedure because the exact number/name of queues are not known until running. Since I have to use a Map, I think I can use either

  • HashMap together with lock/synchronized
  • ConcurrentHashMap

I want to avoid using explicit lock, so I choose ConcurrentHashMap. However, using ConcurrentHashMap doesn't mean my program ConcurrentHashMap is thread-safe, the idle between containsKey() and put() might cause some chaos. So I consider using its putIfAbsent() method.

However, when I call putIfAbsent(queuename, new MySerializer()), I find it creates a new instance of MySerializer everytime I call putIfAbsent. But if I don't use putIfAbsent, I'll have to use something like a lock.

My question is how to concurrently add elements into ConcurrentHashMap while avoiding using lock at the same time?


Solution

  • Java 8 added new methods to the Map interface which allow the potentially-new value to be evaluated lazily. For example:

    map.computeIfAbsent(queuename, MySerializer::new);