关于这个问题(Java thread safety - multiple atomic operations?),我不想再提出更多的问题,但现在我有了这样的疑问:
private final Map<String, Set<String>> data = Maps.newConcurrentMap();
... then in a method ...
if (data.containsKey("A")) {
data.get("A").add("B");
}应该是这样的:
synchronized(data) {
if (data.containsKey("A")) {
data.get("A").add("B");
}
}为了线程安全。对吗?
所以操作是原子的,但是组合它们需要同步,对吗?在这种情况下,当我们手动处理同步时,只使用简单的HashMap而不是并发的会有意义吗?
在CHM中有什么方法可以用原子的方式来完成这个工作吗?
发布于 2017-01-13 02:00:52
在特定情况下,您可能需要使用 method of ConcurrentHashMap
data.computeIfPresent("A", (k, v) -> { v.add("B"); return v; } );来自javadocs:
如果指定键的值存在,则尝试计算给定键及其当前映射值的新映射。整个方法调用都是原子式执行的。
因此不需要显式同步。
发布于 2017-01-13 02:02:53
synchronised(data) {
if (data.containsKey("A")) {
data.get("A").add("B");
}
}你可能需要显示更多的代码。
只看这一点,唯一可能的问题是,在您的"A"检查之后,有人删除了在if中找到的集合。如果您从未删除映射项,则根本不需要同步.
如果同时删除映射项,则可以使用computeIfPresent到达更新后的地图。
你也可以
Set<String> set = data.get("A");
if (set != null) set.add("B");由于您实际上并没有生成一个新的集合,所以我发现这比computeIfPresent (它应该计算一个新的值)更符合惯例。
请注意,您需要使所有这些设置线程安全以及。
https://stackoverflow.com/questions/41625992
复制相似问题