2

我是 Java 线程的新手,我需要从几个活动线程访问数据结构。我听说java.util.concurrent.ConcurrentHashMap是线程友好的。synchronized(map){} 访问 ConcurrentHashMap 时是否需要使用它,否则它会自行处理锁?

4

5 回答 5

5

它自己处理锁,实际上您无法访问它们(没有其他选择)

您可以synchronized在特殊情况下用于写入,但很少需要这样做。例如,如果您需要实现自己的putIfAbsent,因为创建对象的成本很高。

使用 syncrhonized 进行读取会破坏使用并发集合的目的。

于 2012-08-30T09:41:11.337 回答
3

ConcurrentHashMap仅适用于您不需要比提供的开箱即用更多的原子性的情况。例如,如果您需要获取一个值,对其进行操作,然后设置一个新值,所有这些都在原子操作中,如果没有外部锁定,这是无法实现的。

在所有这些情况下,没有什么可以替代代码中的显式锁,使用此实现而不是基本的HashMap.

于 2012-08-30T09:54:35.143 回答
2

不,你不需要,但是如果你需要依赖内部同步,你应该使用Collections.synchronizedMap。来自的javadoc ConcurrentHashMap

在依赖线程安全但不依赖同步细节的程序中,此类与 Hashtable 完全可互操作。

实际上它不会在整个数据结构上同步,而是在它的子部分(一些桶)上同步。这意味着ConcurrentHashMap' 的迭代器是弱一致的,并且映射的大小可能不准确。(但另一方面它的 put 和 get 操作仍然是一致的并且吞吐量更高)

于 2012-08-30T09:47:07.553 回答
2

简短回答:不,您不需要使用synchronized(map).
长答案:

  • 提供的所有操作ConcurrentHashMap都是线程安全的,您可以调用它们而不必担心锁定
  • 但是,如果您需要在代码中进行一些原子操作,您仍然需要在客户端进行某种锁定
于 2012-08-30T09:41:28.957 回答
-1

除了它提供的并发特性,concurrenthmp还有一个更重要的特性需要注意,那就是故障安全迭代器。使用 CHMP 只是因为他们想在迭代时编辑用于放置/删除的条目集。 是另一个。但 ConcurrentModificationException 可能出现在上述情况下。Collections.synchronizedMap(Map)

于 2016-08-02T18:38:37.653 回答