What is the preferred way to modify a value in ConcurrentHashMap?

concurrency, concurrenthashmap, java, thread-safety

Solution

A) is the better option, for two reasons:

- Since in your scenario reads are more frequent, you should reduce the amount of overhead for them. Adding additional synchronization (such as `volatile`) works against you in this case.

- By using mutable objects with additional custom safeguards (which may have bugs) you're pretty much defeating the point of making your life easier by using `ConcurrentHashMap`.

Problem

Let's say I have a Concurrent Map that is high-read, low-write, and needs to store application data: ``` ConcurrentMap<UUID, Data> map = new ConcurrentHashMap<UUID, Data>(); ``` Then, during startup and through user input, data is added to the map: ``` public void createData(Data newData) { map.put(newId, newData); // etc... } ``` If I then need to change the data, should I: A) Make the Data class objects immutable, and then conduct a put operation every time a change is needed for a Data object: ``` public void changeData(UUID oldId, Foo newInfo) { Data oldData = map.get(oldId); Data newData = new Data(oldData, newInfo); // Constructor for demo only map.put(newData); saveToDatabase(newData); } ``` B) Make the Data class objects mutable yet thread-safe with volatile fields, atomic references or final concurrent fields, and simply modify the object as needed: ``` public void changeData(UUID oldId, Foo newInfo) { Data data = map.get(id); data.changeSomething(newInfo); saveToDatabase(data); } ``` C) None of the above

Original source