0

当必须调整地图大小以容纳更多项目时会发生什么?如果在调整大小时另一个线程调用 get() 会发生什么?

4

3 回答 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 回答