【发布时间】:2015-01-19 22:01:44
【问题描述】:
我阅读了有关 Java ConcurrentHashMap 用法的所有内容及其相反的内容。我希望我的问题将有助于澄清一些看起来很简单的事情(提供最新的答案)。
我有一张这样的地图:
ConcurrentHashMap<Integer, ClassA> map = new ConcurrentHashMap<Integer, ClassA>()
我正在使用 ConcurrentHashMap 来保持放置和获取操作线程的安全。我的 ClassA 有一些整数/字符串属性和字符串集合。
现在我想知道如何安全地更新我的映射对象。如果我想创建一个方法来通过添加一个新字符串来更新我的地图中的对象,我有类似的东西:
synchronized(map)
{
Collection<String> strings = map.get(id).getStrings();
if(!strings.contains(newString)) //strings can't be null
{
strings.add(newString);
}
}
这段代码对并发读/写安全吗?可以通过使用 Java API 以不同的方式完成吗?
【问题讨论】:
-
您的示例可能有一些错误。现在 synchronized 块内的代码与 map 无关。有一个名为 events 的变量,但我不知道那是什么 - 我猜是你的地图。如果是这样的话,那么你真的不需要在地图上同步。提取此逻辑,将其推送到 ClassA 中,然后进行一些同步。
-
确实,我用正确的名称更新了描述。这确实是我的地图。我希望同步地图以实际锁定整个表并防止对我的映射对象进行任何并发更改。你能详细说明“一些同步”吗?
-
最简单的方法是在 ClassA 中创建 public void synchronized add(String newString) 方法。 ClassA 实例的并发修改将被同步,您不必在地图上同步。
-
@bbankowski 如果您通过创建外部同步层来确保所有操作的安全,那么使用 ConcurrentHashMap 是没有意义的
-
@lbalazscs 我认为仍然可能存在,因为我们在这里看不到 put/get 操作。当然,最好能看到全班同学,做出正确的决定。
标签: java multithreading concurrency concurrenthashmap