如果在使用时 ConcurrentMap 中不存在新元素,如何添加新元素

How to add a new element in case it does not exist in a ConcurrentMap while are using

我正在使用线程进行 Java 开发,事实上我没有太多想法。它比我想象的要复杂。

问题是我必须将几个对象组合在一个ConcurrentMap 中,如果该对象不在ConcurrentMap 中必须添加它,否则修改它。

对于修改数据的部分我没有问题,但是当我想更新时我得到一个“递归更新”错误,我不知道我还能对 modify/add 我的 ConcurrentMap 做些什么并使其成为线程安全的。

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

}   

如果密钥不存在,您只需创建一个新的 person 对象并 return 它。 ConcurrentMap#Compute 将确保整个调用是原子的。 如果在 compute 中不存在 key 时调用 putIfAbsent ,则会导致无限循环。 (无限循环发生在 ConcurrentHashMap#putVal 方法中)。

        myData.compute("A", (key, person) -> {
            if (person== null) {
                person = new Person();
            } else {
                //Update data, this part its ok!

            }
            return person;
        });

参见 ConcurrentMap#compute JDK 文档:

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))

我昨晚找到了解决方案,但我忘了回答这张工单。

我意识到在一个新项目中做了一些非常简单的测试,当我应用一个简单的 lambda ex: (k,val) -> v == null 时,我可以做一个 put ? “新文本”:“修改”

然后,我只是看到我在生成新对象时没有执行 return,所以它不是实例。

初学者的错误呵呵,但希望对和我有同样错误的人有所帮助:)

此致!

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