java - 当 ConcurrentHashMap 调整大小时,读取会如何发生?

标签 java multithreading thread-safety locking concurrenthashmap

假设有 2 个线程。两个线程都在 Concurrent HashMap 的同一个 Hashtable 上工作。

线程 T1 正在通过调用 map.get() 进行读取,而不是迭代,线程 T2 正在将对象放入 ConcurrentHashMap 的同一个 HashTable 中。

现在,如果达到阈值级别,则 T2 将尝试调整 Concurrent HashMap 中的 Hashtable 大小。 那么,T1 是否会被阻塞读取,还是从旧的缓存结构中读取?

答案: 我假设 Entry Class 的 value 和 Entry volatile ,它将直接从主内存为我们提供最后更新的值。 没有脏读或缓存读。

我读过很多博客,甚至javadoc,但没有一个为这种情况提供明确的答案。让我知道您的意见。

最佳答案

来自docs :

Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove). Retrievals reflect the results of the most recently completed update operations holding upon their onset. (More formally, an update operation for a given key bears ahappens-before relation with any (non-null) retrieval for that key reporting the updated value.) For aggregate operations such as putAll and clear, concurrent retrievals may reflect insertion or removal of only some entries. Similarly, Iterators, Spliterators and Enumerations return elements reflecting the state of the hash table at some point at or since the creation of the iterator/enumeration. They do not throw ConcurrentModificationException. However, iterators are designed to be used by only one thread at a time.

因此,如果您在 ConcurrentHashMap 实例上进行迭代,而另一个线程修改它,则不会发生任何不良情况,您的线程也不会被阻塞,您只会看到一些较旧的快照。

另请参阅:

关于java - 当 ConcurrentHashMap 调整大小时,读取会如何发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48181672/

相关文章:

java - 描述 API 用途

java - 将驱动程序/对象传递给其他页面/类 - java.lang.NullPointerException

c++ - 如何在 Visual Studio 中使用 C++11 线程

multithreading - 在线程中使用TADOQuery

c++ - 对共享数据的线程安全访问 - 读/写实际上发生并且不会发生重新排序

Java : Comparing two ArrayLists, 删除不匹配的值

java - Breakout(游戏项目)-让球位于 Racket 中心-Java

c# - 复用一个BackgroundWorker,取消等待

java - 将监听器与线程一起使用

multithreading - 线程隔离调用和信号量隔离调用的区别