繁体   English   中英

如何锁定 ConcurrentHashMap 中的键

[英]How to lock on key in a ConcurrentHashMap

我正在将一个由线程创建的对象缓存到地图中。 对象的创建是昂贵的,所以我不希望多个线程运行来创建对象,因为 put() 没有返回。 一旦一个线程尝试为该键创建对象,其他线程不应尝试创建该对象,即使 put 尚未完成。 使用 computeIfAbsent() 是否可以在该特定键上获得“锁定”? 如果没有,还有其他方法可以实现这一目标吗?

> 使用 computeIfAbsent() 是否可以在该特定键上获得“锁定”?

是的; 根据ConcurrentHashMap.computeIfAbsent(...)的Javadoc

整个方法调用以原子方式执行,因此每个键最多应用一次该函数。

这就是方法的全部意义所在。

但是,需要明确的是,锁并不完全特定于那把钥匙。 相反, ConcurrentHashMap通常通过将映射拆分为多个段,并且每个段拥有一个锁来工作。 这允许大量并发,通常是最有效的方法; 但是您应该知道,这意味着某些线程可能会阻塞您的对象创建,即使它们实际上并未触及同一个键。

如果这对您来说是个问题,那么另一种方法是使用诸如ConcurrentHashMap<K, AtomicReference<V>>之类的东西来将添加映射条目与填充映射条目分离。 AtomicReference<V>没有computeIfAbsent方法,但此时您可以使用普通的双重检查锁定与get()synchronized的组合。)

进行了一些研究,但我们可能追求的是 Java ConcurrentHashMap等效于 .NET 的.TryAdd方法。 哪个是Java世界是:

放置如果不存在

public V putIfAbsent(K key, V value);

如果指定的键尚未与值关联,则将其与给定值关联。 这相当于:

 if (!map.containsKey(key)) return map.put(key, value); else return map.get(key);

除了动作是原子执行的。

我知道必须存在原子add操作; 只是不容易找到。 (这很奇怪,因为这就像任何人都需要打电话的第一件事)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM