Home > Back-end >  How to add a new element in case it does not exist in a ConcurrentMap while are using
How to add a new element in case it does not exist in a ConcurrentMap while are using

Time:03-02

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;
            }
            
        });
    
    }  
  • Related