ConcurrentHashMap如何在内部工作?

时间:2012-08-03 09:33:59

标签: java collections concurrency hashmap

我正在阅读关于Java中的并发的官方Oracle文档,我想知道

返回的Collection之间有什么区别?
public static <T> Collection<T> synchronizedCollection(Collection<T> c);

并使用例如

ConcurrentHashMap。我假设我在synchronizedCollection(Collection<T> c)上使用HashMap。我知道一般来说,同步集合本质上只是我HashMap的装饰器所以很明显ConcurrentHashMap的内部结构有所不同。您是否有关于这些实施细节的信息?

编辑:我意识到源代码是公开的: ConcurrentHashMap.java

6 个答案:

答案 0 :(得分:42)

我会阅读source of ConcurrentHashMap因为它在细节上相当复杂。简而言之,它有

  • 可以独立锁定的多个分区。 (默认为16)
  • 使用并发锁定操作来实现线程安全而不是同步。
  • 具有线程安全的迭代器。 synchronizedCollection的迭代器不是线程安全的。
  • 不公开内部锁。 synchronizedCollection确实。

答案 1 :(得分:22)

ConcurrentHashMapjava.util.HashTable类非常相似,只是ConcurrentHashMap提供比HashTablesynchronizedMap更好的并发性。在您阅读地图时,ConcurrentHashMap不会锁定地图。此外,ConcurrentHashMap在写入时不会锁定整个Map。它只在内部锁定正在写入的Map部分。

另一个区别是,如果在迭代时更改ConcurrentModificationException,则ConcurrentHashMap不会抛出ConcurrentHashMapIterator并非设计为由多个线程使用,而synchronizedMap可能会抛出ConcurrentModificationException

答案 2 :(得分:15)

这篇文章帮我理解了Why ConcurrentHashMap is better than Hashtable and just as good as a HashMap

  

Hashtable提供对其条目的并发访问,只需要一个小小的警告,整个地图都被锁定以执行任何类型的操作。   虽然这种开销在正常的Web应用程序中是可忽略的   负载,在重负载下,它可能导致延迟响应时间和   无缘无故地过度使用你的服务器。

     

这是ConcurrentHashMap的步骤。它们提供了所有功能   Hashtable的表现几乎和HashMap一样好。   ConcurrentHashMap通过一种非常简单的机制实现了这一目标。   该集合不是地图宽锁,而是维护16的列表   默认情况下,每个锁都用于保护(或锁定)单个锁   地图桶。这实际上意味着16个线程可以修改   一次性收集(只要他们都在努力   不同的水桶)。事实上,没有执行此操作   锁定整个地图的集合。并发级别   集合,可以同时修改它的线程数   没有阻塞,可以增加。然而,更高的数字意味着更多   维护这个锁列表的开销。

答案 3 :(得分:5)

Hashtable中的“可伸缩性问题”在Collections.synchronizedMap(Map)中以完全相同的方式出现 - 它们使用非常简单的同步,这意味着只有一个线程可以同时访问地图。 / p>

当您进行简单的插入和查找时(除非您非常密集地执行此操作),这不是什么大问题,但是当您需要遍历整个Map时会成为一个大问题,这可能需要很长时间才能完成映射 - 当一个线程执行此操作时,所有其他线程必须等待,如果他们想要插入或查找任何内容。

ConcurrentHashMap使用非常复杂的技术来减少同步的需要,并允许多个线程进行并行读取访问而不进行同步,更重要的是,提供了一个不需要同步的迭代器,甚至允许在过程中修改Map。 interation(虽然它不能保证是否会返回在迭代期间插入的元素)。

答案 4 :(得分:4)

synchronizedCollection()返回的是一个对象,其所有方法都在 this 上同步,因此对此类包装器的所有并发操作都是序列化的。 ConcurrentHashMap是一个真正的并发容器,具有优化的细粒度锁定,以尽可能降低争用。看看源代码,你会看到里面的内容。

答案 5 :(得分:0)

ConcurrentHashMap实现提供并发性的ConcurrentMap。 在内部,它的迭代器设计为一次只能由一个线程使用,以保持同步。 该地图在并发方面得到了广泛使用。