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

发布于 2025-01-11 03:26:53 字数 685 浏览 0 评论 0原文

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

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

对于修改数据的部分,我没有问题,但是当我想更新时,我收到“递归更新”错误,我不知道我还能做什么来修改/添加我的 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;
    });

}   

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

}   

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

坐在坟头思考人生 2025-01-18 03:26:53

如果该键不存在,您只需创建一个新的 person 对象并返回它。 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 文档:

尝试计算指定键及其当前映射值的映射(如果没有当前映射,则为 null)。例如,要创建字符串消息或将其附加到值映射:
map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))

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

难以启齿的温柔 2025-01-18 03:26:53

我昨晚找到了解决方案,但我忘了回复这张​​票。

我意识到在一个新项目中做了一些非常简单的测试,当我应用一个简单的 lambda ex 时,我可以进行 put: (k,val) -> v == 空? " new text" : "modify"

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

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

问候!

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

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;
            }
            
        });
    
    }  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文