【发布时间】:2011-04-14 17:03:17
【问题描述】:
我一直在使用 Java 的 ConcurrentMap 来制作可以从多个线程中使用的地图。 putIfAbsent 是一个很好的方法,并且比使用标准映射操作更容易读/写。我有一些看起来像这样的代码:
ConcurrentMap<String, Set<X>> map = new ConcurrentHashMap<String, Set<X>>();
// ...
map.putIfAbsent(name, new HashSet<X>());
map.get(name).add(Y);
在可读性方面这很好,但它确实需要每次都创建一个新的 HashSet,即使它已经在地图中。我可以这样写:
if (!map.containsKey(name)) {
map.putIfAbsent(name, new HashSet<X>());
}
map.get(name).add(Y);
有了这个改变,它失去了一点可读性,但不需要每次都创建 HashSet。在这种情况下哪个更好?我倾向于支持第一个,因为它更具可读性。第二个会表现得更好,可能更正确。也许有比这两种方法更好的方法。
以这种方式使用 putIfAbsent 的最佳做法是什么?
【问题讨论】:
-
在您的示例中,Value-HashSet 也需要是 ConcurrentHashSet,否则这仍然不是线程安全的。
-
Tom Hawtin 的解决方案正是您想要的
-
正如 Markus 所指出的,值类型(在这种情况下为 Set)确实需要也是线程安全的,因为它可以被多个线程同时访问。
-
即使你使用Tom Hawtin的回复,也是不完整的,我相信和你自己的建议是等价的。
标签: java performance concurrency concurrenthashmap