52

我正在阅读有关 Java 并发的 Oracle 官方文档,我想知道Collection返回的a 之间可能有什么区别

public static <T> Collection<T> synchronizedCollection(Collection<T> c);

并使用例如

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

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

4

6 回答 6

50

我会阅读ConcurrentHashMap 的源代码,因为它的细节相当复杂。简而言之,它有

  • 可以独立锁定的多个分区。(默认为 16 个)
  • 使用并发锁操作来保证线程安全而不是同步。
  • 具有线程安全的迭代器。synchronizedCollection 的迭代器不是线程安全的。
  • 不暴露内部锁。synchronizedCollection 可以。
于 2012-08-03T09:39:40.243 回答
27

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

ConcurrentModificationException另一个区别是,如果在ConcurrentHashMap迭代时更改了 ConcurrentHashMap ,则不会抛出异常。虽然Iterator它不是为多个线程使用而设计的,但synchronizedMap可能会抛出ConcurrentModificationException

于 2012-08-03T09:38:26.160 回答
18

这是帮助我理解它的文章为什么 ConcurrentHashMap 比 Hashtable 更好,并且和 HashMap 一样好

Hashtable 提供对其条目的并发访问,但有一点需要注意的是,整个地图被锁定以执行任何类型的操作。虽然这种开销在正常负载下的 Web 应用程序中是可以忽略的,但在重负载下,它可能会导致响应时间延迟和服务器负担过重。

这就是 ConcurrentHashMap 介入的地方。它们提供了 Hashtable 的所有功能,性能几乎与 HashMap 一样好。ConcurrentHashMap 通过一个非常简单的机制来实现这一点。默认情况下,集合维护一个包含 16 个锁的列表,而不是映射范围的锁,每个锁用于保护(或锁定)映射的单个存储桶。这实际上意味着 16 个线程可以一次修改集合(只要它们都在不同的存储桶上工作)。事实上,这个集合没有执行任何锁定整个地图的操作。集合的并发级别,可以不阻塞地同时修改它的线程数,可以增加。但是,更高的数字意味着维护此锁列表的开销更大。

于 2012-08-03T10:00:21.787 回答
5

的“可扩展性问题”以Hashtable完全相同的方式存在Collections.synchronizedMap(Map)- 它们使用非常简单的同步,这意味着只有一个线程可以同时访问映射。

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

使用ConcurrentHashMap非常复杂的技术来减少同步的需要并允许多个线程在不同步的情况下并行读取访问,更重要的是,提供了一个不需要同步的迭代器,甚至允许在交互期间修改 Map(尽管它不保证是否或不返回在迭代期间插入的元素)。

于 2013-03-01T09:05:33.440 回答
4

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

于 2012-08-03T09:38:25.260 回答
0

ConcurrentHashMap 实现了提供并发性的 ConcurrentMap。在内部深处,它的迭代器设计为一次仅由一个线程使用,以保持同步。此映射在并发中广泛使用。

于 2018-12-04T06:18:55.130 回答