当必须调整地图大小以容纳更多项目时会发生什么?如果在调整大小时另一个线程调用 get() 会发生什么?
user2538100
问问题
291 次
3 回答
4
你的问题是如果另一个线程在调整地图大小时调用 get() 会发生什么,这表明普遍缺乏对 Java 内存模型的直觉。具体来说,如果您使用的地图实现不是线程安全的,那么在调用 get() 时(在调整大小的过程中或地图完全空闲时)将无关紧要:来自另一个线程的调用总是会中断,因为写可见性问题。
简单来说,Java中只有两个条件:线程安全和非线程安全。无需进一步的细节。
于 2013-11-11T18:55:52.460 回答
0
我将尝试解释那里会发生什么。以防万一 -不应该这样做。
据我了解HashMap
实现,如果您使用单个线程写入它,它不会崩溃,但可能找不到您的项目。对于两个并发线程,它会很早就崩溃,因为ConcurrentModificationException
.
为什么不会崩溃
- 调整大小操作
HashMap
是一种原子操作 - 它首先分配您的表并将项目重新索引到其中,然后用新表替换现有表 - 表大小会增加,但不会缩小,因此即使索引功能损坏,您仍然在界限内。
get
永远不会抛出空指针异常 - 可以检查getEntry(Object key)
永远不会抛出NullPointerException
.
为什么它可能找不到您的项目
因为table[hash(key)]
操作是非原子的。当您有旧地图的哈希值时,您可能会遇到这种情况,但在调整大小后它已经是新地图了。
于 2013-11-11T19:57:30.320 回答
0
答案是它会崩溃并抛出异常可能是UnsupportedOperationException。这背后的原因是..
由于 HashMap 不是线程安全的,因此当另一个线程尝试读取数据时,它不会允许并且会发生完全取决于实现的事情。
于 2014-01-29T15:07:58.420 回答