Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 559
oberger Avatar asked Aug 20 '13 16:08

oberger


People also ask

How do you atomically update a value in ConcurrentHashMap?

The compute(Key, BiFunction) method of ConcurrentHashMap class is used to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping is found). This method is used to atomically update a value for given key in ConcurrentHashMap.

Which is better to use synchronized over the map or using ConcurrentHashMap?

Concurrent hashmap allows concurrent read and write. So performance is relatively better than a synchronized map. Multiple threads can't access the map concurrently. So, performance is relatively less than a concurrent hash map.

Which data structure you will use to create custom ConcurrentHashMap?

The underlined data structure for ConcurrentHashMap is Hashtable. ConcurrentHashMap class is thread-safe i.e. multiple threads can operate on a single object without any complications.

Can we change the concurrency level in ConcurrentHashMap?

ConcurrentHashMap is a subclass of HashMap and is designed to be used in multi-threaded environments. It maintains a configurable concurrency level (default value of 16), which can be specified while creating the map.


2 Answers

A) is the better option, for two reasons:

  1. 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.
  2. 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.
like image 80
mikołak Avatar answered Sep 21 '22 10:09

mikołak


If you have an option of making an immutable class, you would be much better off with your implementation #A: in-place modifications are significantly harder to implement and maintain.

Sometimes going the immutable route may not be an option, because of the need to make frequent modifications to a relatively large object. In this case you may want to reconsider the application of the concurrent hash map to your design, because the fact that it is synchronized does not give you too much an advantage.

like image 41
Sergey Kalinichenko Avatar answered Sep 19 '22 10:09

Sergey Kalinichenko