假如 ConcurrentHashMap 正在扩容,而有一个线程调用了 get() 方法,当 get() 方法在链表中遍历查找时,链表为 a1 -> a2 -> b1 -> b2 -> a3。
假设我们要查找的为 a3, 此时遍历到 b1 时, 扩容导致 b1 -> b2 移到了新的位置,a1 -> a2 -> a3 留在了原位置,那么此 get() 方法会返回 null嘛? 但原本 hashMap 中是存在 a3 的。
假如 ConcurrentHashMap 正在扩容,而有一个线程调用了 get() 方法,当 get() 方法在链表中遍历查找时,链表为 a1 -> a2 -> b1 -> b2 -> a3。
假设我们要查找的为 a3, 此时遍历到 b1 时, 扩容导致 b1 -> b2 移到了新的位置,a1 -> a2 -> a3 留在了原位置,那么此 get() 方法会返回 null嘛? 但原本 hashMap 中是存在 a3 的。
去看了一篇讲ConcurrentHashMap的,结果就是上边说的,扩容时是copy&move,你可以看一下这篇文章ConcurrentHashMap1.8 - 扩容详解,讲的不错,文章最后还有ConcurrentHashMap相关问题的自问自答
8 回答6.4k 阅读
1 回答4.2k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
2 回答3.2k 阅读
2 回答3.9k 阅读
3 回答1.7k 阅读✓ 已解决
1 回答2k 阅读✓ 已解决
这是一个有趣的问题~我理解是不会的。HashMap的resize是copy&move,即它会复制当前的元素并移动到新的桶列表中,再将扩容完成的桶列表替换掉当前的桶列表。因此你取到的是某一刻桶列表的快照,而resize并不会影响这个快照,而modify操作如put/remove则有可能会改变它。