HashMap resize()同时单线程写入和多线程读取
首先,我是否正确地假设,如果总是有一个编写器线程,那么我应该可以安全地使用 HashMap
而不是 ConcurrentHashMap
?
在 HashMap#resize
(java 17) 中,它的作用是
Node<K,V>[] oldTab = table; //table is the underlying storage transient Node<K,V>[] table
...
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
table = newTab;
// copy data from oldTab to newTab
...
如果我有另一个线程开始读取,而 将数据从 oldTab 复制到 newTab
尚未完成,我就注定失败由于 HashMap#get
从 table
检索值,而由于 table = newTab
现在是一个空数组,因此数据错误?
我不明白的是,为什么不先执行 将数据从 oldTab 复制到 newTab
步骤,然后再将 table
替换为 newTab
(表 = newTab
):
Node<K,V>[] oldTab = table;
...
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
// copy data from oldTab to newTab
...
table = newTab;
First of all, am I correct to assume that if there's always going to be a single writer thread, then I should be safe to use HashMap
but not ConcurrentHashMap
?
In HashMap#resize
(java 17), what it does is
Node<K,V>[] oldTab = table; //table is the underlying storage transient Node<K,V>[] table
...
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
table = newTab;
// copy data from oldTab to newTab
...
If I have another thread starts reading while copy data from oldTab to newTab
is not finished, I'll be doomed with wrong data since HashMap#get
retrieves value from table
, which is now an empty array because of table = newTab
?
What I don't understand is why not do the copy data from oldTab to newTab
step first, before replacing table
with newTab
(table = newTab
):
Node<K,V>[] oldTab = table;
...
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
// copy data from oldTab to newTab
...
table = newTab;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,这不是线程安全的。作为 的 javadoc HashMap 指出:
事实上,一个线程正在更改映射,而其他线程正在同时读取,这一事实根据定义是不安全的。您将需要使用
ConcurrentHashMap
或Collections.synchronizedMap
或其他同步解决方案。No, this is not thread safe. As the javadoc of HashMap states:
The fact that one thread is changing the map while others are reading concurrently is by definition unsafe. You will need to use
ConcurrentHashMap
orCollections.synchronizedMap
or another synchronization solution.