了解concurrentHashMap

时间:2015-09-01 09:46:14

标签: java multithreading dictionary

众所周知,ConcurrenthashMap类允许我们安全地使用迭代器。据我所知,Map的来源是通过将当前Map状态存储到迭代器本身来实现的。这是表示迭代器的内部类(在调用iterator()时创建了一个子项):

abstract class HashIterator {
        int nextSegmentIndex;
        int nextTableIndex;
        HashEntry<K,V>[] currentTable;
        HashEntry<K, V> nextEntry;
        HashEntry<K, V> lastReturned;

        //Methods and ctor
}

但是如果某个线程在迭代器的构造过程中写入了Map呢?那么我们是否得到了地图的非威慑状态?

事情既不是Map的同步方法。 ReentrantLock方法有put,但就是这样(据我所知)。所以,我不明白迭代器如何支持一个正确的状态,即使一些线程在构造过程中写入地图?

2 个答案:

答案 0 :(得分:3)

迭代器提供弱一致的状态。它没有提供数据的事务视图。它只提供你会看到所有键/值,如果它没有被改变,如果是,你可能会或可能不会看到这种改变,但你不会得到错误。

答案 1 :(得分:2)

来自ConcurrentHashMap的<{3}}:

  

检索操作(包括get)一般不会阻塞,所以可能   与更新操作重叠(包括put和remove)。检索   反映最近完成的更新操作的结果   坚持他们的发作。对于诸如putAll和。之类的聚合操作   清除,并发检索可能仅反映插入或删除   一些条目。同样,Iterators和Enumerations返回元素   反映哈希表的状态在某个时刻或之后的某个时刻   创建迭代器/枚举。他们不扔   ConcurrentModificationException的。 但是,迭代器的设计是   一次仅由一个线程使用。

现在回答问题。

  

但是如果某个线程在Map期间写入了什么呢?   构造迭代器?

如上所述,迭代器代表某个时间点的状态。所以它可能不是最近的州。

  

即使某个线程,迭代器如何支持正确的状态   在构造过程中写入地图?

保证在迭代期间放置/删除时不会破坏。但是,无法保证一个线程会看到另一个线程执行的映射更改(无需从映射中获取新的迭代器)。迭代器保证在创建时反映地图的状态。未来的变化可能会反映在迭代器中,但它们并非必须如此。