我正在阅读Java Concurrecny这本书。在第85页的第5.2.1节中,它讨论了ConcurrentHashMap及其优点。然而,在一部分中,书籍声称
ConcurrentHashMap返回的迭代器非常一致。这个 意味着这个迭代器可以容忍并发修改, 遍历构造迭代器时存在的元素,以及 可能(但不保证)反映对该集合的修改 在构造迭代器之后。
从我理解为什么并发程序中的整个同步点是允许线程以一致的方式访问共享资源,而ConcurrentHashMap并没有真正实现这一点。那么为什么要使用呢?
答案 0 :(得分:16)
重点是在不需要时避免同步。如果您不介意在某些情况下看到新元素而在其他情况下没有看到它们,那么使用ConcurrentHashMap
的迭代器可能会比 显着便宜,以防止其他线程在您添加项目时重复迭代或在创建迭代器时获取一致的快照。
所以是的,当你需要同步和一致的迭代器时,你需要一个替代方案 - 但是当你不需要时,你可以利用ConcurrentHashMap
提供的更有效的迭代器。
答案 1 :(得分:1)
ConcurrentHashMap
应该是线程安全的。但是,不应该跨线程一致。
迭代ConcurrentHashMap
时,迭代器会在您请求时获取哈希映射的副本(此副本以线程安全的方式进行)并迭代该副本。是的,在迭代该副本时,没有什么可以保证,一些地图条目不会被删除。但是以这种方式删除的地图条目 woud仍然存在于你的迭代器中。
答案 2 :(得分:1)
一切都取决于您需要多么强大的一致性。如果您需要强大的 - 而不是互斥或其他操作子集将提供您所需的。
但是,有时您需要更弱的要求,但例如需要说无锁属性,因为您需要保证吞吐量。另一方面,您可能根本不需要迭代器或对它们有更严格的限制。
因此,如果你需要的只是在线程ConcurrentHashMap
之间共享地图(比如在剧院预订它的地方)将提供你所需要的东西 - 如果你有许多工作线程可能会更快,因为你避免互斥同步。另一方面,速度是有代价的 - 迭代器提供的视图没有必要对应于它创建时的收集状态,它可能会遗漏一些后创建的元素(通常在多处理器系统中happens-before
关系很棘手)
编辑:正如John Wesley王子所指出的那样,我在看到和写作时想到了ConcurrentSkipListMap
。 ConcurrentHashMap
。大多数要点仍然存在,除了关于无锁的部分(以及来自它的所有内容,如保证吞吐量等)。