如果你在使用ConcurrentMap的putIfAbsent之前检查map是否包含Key [英] Should you check if the map containsKey before using ConcurrentMap's putIfAbsent

查看:2664
本文介绍了如果你在使用ConcurrentMap的putIfAbsent之前检查map是否包含Key的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直使用Java的ConcurrentMap作为可以从多个线程使用的映射。 putIfAbsent是一个伟大的方法,比使用标准地图操作更容易读/写。我有一些代码看起来像这样:

I have been using Java's ConcurrentMap for a map that can be used from multiple threads. The putIfAbsent is a great method and is much easier to read/write than using standard map operations. I have some code that looks like this:

ConcurrentMap<String, Set<X>> map = new ConcurrentHashMap<String, Set<X>>();

// ...

map.putIfAbsent(name, new HashSet<X>());
map.get(name).add(Y);

可读性这是伟大的,但它需要创建一个新的HashSet每次,即使它已经在地图。我可以这样写:

Readability wise this is great but it does require creating a new HashSet every time even if it is already in the map. I could write this:

if (!map.containsKey(name)) {
    map.putIfAbsent(name, new HashSet<X>());
}
map.get(name).add(Y);

使用此更改会失去一点可读性,但不需要每次都创建HashSet。在这种情况下哪个更好?我倾向于与第一个,因为它更可读。第二个将表现更好,可能更正确。

With this change it loses a bit of readability but does not need to create the HashSet every time. Which is better in this case? I tend to side with the first one since it is more readable. The second would perform better and may be more correct. Maybe there is a better way to do this than either of these.

以这种方式使用putIfAbsent的最佳做法是什么?

What is the best practice for using a putIfAbsent in this manner?

推荐答案

并发很难。如果你打算使用并发映射,而不是直接锁定,你可能会去。

Concurrency is hard. If you are going to bother with concurrent maps instead of straightforward locking, you might as well go for it. Indeed, don't do lookups more than necessary.

Set<X> set = map.get(name);
if (set == null) {
    final Set<X> value = new HashSet<X>();
    set = map.putIfAbsent(name, value);
    if (set == null) {
        set = value;
    }
}

(通用stackoverflow免责声明:未测试未编译等)

(Usual stackoverflow disclaimer: Off the top of my head. Not tested. Not compiled. Etc.)

更新: 1.8已添加 computeIfAbsent 默认方法到 ConcurrentMap (和 Map 这是有趣的,因为 ConcurrentMap )。 (和1.7添加了钻石操作符<> 。)

Update: 1.8 has added computeIfAbsent default method to ConcurrentMap (and Map which is kind of interesting because that implementation would be wrong for ConcurrentMap). (And 1.7 added the "diamond operator" <>.)

Set<X> set = map.computeIfAbsent(name, n -> new HashSet<>());

(注意,你负责任何操作的线程安全性 ConcurrentMap 中包含的。)

(Note, you are responsible for the thread-safety of any operations of the HashSets contained in the ConcurrentMap.)

这篇关于如果你在使用ConcurrentMap的putIfAbsent之前检查map是否包含Key的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆