假设有 2 个线程。两个线程都在 Concurrent HashMap 的同一个 Hashtable 上工作。
线程 T1 正在通过调用 map.get() 进行读取,而不是迭代,线程 T2 正在将对象放入 ConcurrentHashMap 的同一个 HashTable 中。
现在,如果达到阈值级别,则 T2 将尝试调整 Concurrent HashMap 中的 Hashtable 大小。 那么,T1 是否会被阻塞读取,还是从旧的缓存结构中读取?
答案:
我假设 Entry Class 的 value 和 Entry
我读过很多博客,甚至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/