【发布时间】:2018-04-17 01:11:59
【问题描述】:
我知道 Java 中的 ConcurrentHashMap 及其众多好处,但我不太清楚为什么像同步 HashMap 这样的实现需要在每个函数调用上同步。
对我来说,感觉就像如果你有一个 HashMap,其唯一的函数是 put(k, v) 和 get(k),那么只有 put 函数需要同步,因为即使你要在调用后调整 hashMap 的大小put,那么您仍然可以在执行调整大小时授予安全读取访问权限。阅读器线程可以简单地从之前调整大小的版本中读取。调整大小完成后,编写器线程将替换引用,以便当前对 get 的所有调用都指向调整大小后的 HashMap 版本。
我是否遗漏了一些明显的东西?
【问题讨论】:
-
这会使 put() 效率极低:它必须复制整个 HashMap,然后在完成后使用该副本。这是 CopyOnWriteArrayList 使用的策略,但是如果您对列表进行多次写入,则效率低下。
-
同步不是这样工作的。您需要同步写入和读取,否则读取可能会看到陈旧的或更糟糕的不一致值。
-
@assylias,我明白你为什么会得到一个陈旧的价值。但对我来说,不一致的值只有在 put 操作对已经存在的条目执行突变时才会发生。对吗?
-
@D.Rek,有趣的是,我确实认为这部分是原子的。谢谢
-
实际上对象的分配是原子的。详情请查看我的回答。
标签: java multithreading concurrency hashmap