I'm working on a Java development with threads and the truth is that I don't have much of an idea. It is being more complicated than I thought.
The thing is that I must group several objects in a ConcurrentMap, if the object is not in the ConcurrentMap must add it and otherwise modify it.
For the part of modifying the data I have no problems, but when I want to update I get a "Recursive update" error, I don't know what else I can do to modify/add my ConcurrentMap and make it threadSafe.
private final ConcurrentMap<String, Person> myData= new ConcurrentHashMap<>();
private void processMyData(){
myData.compute(String, (key, person) -> {
if (person== null) {
myData.putIfAbsent(key, new Person("Antonio", 0, false));
} else {
//Update data, this part its ok!
person.setConnectedHours(person.getConnectedHours() + 1000);
}
return person;
});
}
If the key doesn't exist, you just need to create a new person
object and return it. ConcurrentMap#Compute
will ensure that the entire invocation is atomic.
If you call putIfAbsent
when key does not exist inside compute
, it will cause an infinite loop. (The infinite loop happens in ConcurrentHashMap#putVal
method).
myData.compute("A", (key, person) -> {
if (person== null) {
person = new Person();
} else {
//Update data, this part its ok!
}
return person;
});
See ConcurrentMap#compute
JDK doc:
Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). For example, to either create or append a String msg to a value mapping: map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))