首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java CHM同步

Java CHM同步
EN

Stack Overflow用户
提问于 2017-01-13 01:25:22
回答 2查看 137关注 0票数 1

关于这个问题(Java thread safety - multiple atomic operations?),我不想再提出更多的问题,但现在我有了这样的疑问:

代码语言:javascript
复制
private final Map<String, Set<String>> data = Maps.newConcurrentMap();

... then in a method ...

if (data.containsKey("A")) {
    data.get("A").add("B");
}

应该是这样的:

代码语言:javascript
复制
synchronized(data) {
    if (data.containsKey("A")) {
        data.get("A").add("B");
    }
}

为了线程安全。对吗?

所以操作是原子的,但是组合它们需要同步,对吗?在这种情况下,当我们手动处理同步时,只使用简单的HashMap而不是并发的会有意义吗?

在CHM中有什么方法可以用原子的方式来完成这个工作吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-13 02:00:52

在特定情况下,您可能需要使用 method of ConcurrentHashMap

代码语言:javascript
复制
data.computeIfPresent("A", (k, v) -> { v.add("B"); return v; } );

来自javadocs:

如果指定键的值存在,则尝试计算给定键及其当前映射值的新映射。整个方法调用都是原子式执行的。

因此不需要显式同步。

票数 2
EN

Stack Overflow用户

发布于 2017-01-13 02:02:53

代码语言:javascript
复制
synchronised(data) {
    if (data.containsKey("A")) {
        data.get("A").add("B");
    }
}

你可能需要显示更多的代码。

只看这一点,唯一可能的问题是,在您的"A"检查之后,有人删除了在if中找到的集合。如果您从未删除映射项,则根本不需要同步.

如果同时删除映射项,则可以使用computeIfPresent到达更新后的地图。

你也可以

代码语言:javascript
复制
Set<String> set = data.get("A");
if (set != null) set.add("B");

由于您实际上并没有生成一个新的集合,所以我发现这比computeIfPresent (它应该计算一个新的值)更符合惯例。

请注意,您需要使所有这些设置线程安全以及。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41625992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档