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;
});
}
CodePudding user response:
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))
CodePudding user response:
I found the solution last night but I forgot to answer this ticket.
I realized doing some very simple tests in a new project that I could make a put when I applied a simple lambda ex: (k,val) -> v == null ? " new text" : "modify"
then, I simply saw that I was not doing the return when I generated the new object so it was not instance.
A beginner mistake hehe but I hope it can be of help to someone who has the same error as me :)
Regards!
private final ConcurrentMap<String, Person> myData= new ConcurrentHashMap<>();
private void processMyData(){
myData.compute(String, (key, person) -> {
if (person== null) {
return new Person("Antonio", 0, false);
} else {
//Update data, this part its ok!
person.setConnectedHours(person.getConnectedHours() 1000);
return person;
}
});
}