java modCount detailed analysis and source code analysis

  • 2020-06-03 06:26:56
  • OfStack

What exactly does modCount do

In the internal implementation of ArrayList,LinkedList,HashMap and so on, we can always see the figure of modCount, modCount literally means the number of changes, but why record the number of changes of modCount?

There is one common feature that you find out is that all of the modCount attributes are thread-unsafe. Why is that? This must have something to do with thread safety. What does it have to do with thread safety

Reading the source code, I found that this thing is only used in the corresponding iterator of this data structure. Take HashMap as an example:


private abstract class HashIterator<E> implements Iterator<E> {
    Entry<K,V> next;    // next entry to return
    int expectedModCount;  // For fast-fail
    int index;       // current slot
    Entry<K,V> current;   // current entry

    HashIterator() {
      expectedModCount = modCount;
      if (size > 0) { // advance to first entry
        Entry[] t = table;
        while (index < t.length && (next = t[index++]) == null)
          ;
      }
    }

    public final boolean hasNext() {
      return next != null;
    }

    final Entry<K,V> nextEntry() {
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      Entry<K,V> e = next;
      if (e == null)
        throw new NoSuchElementException();

      if ((next = e.next) == null) {
        Entry[] t = table;
        while (index < t.length && (next = t[index++]) == null)
          ;
      }
      current = e;
      return e;
    }

    public void remove() {
      if (current == null)
        throw new IllegalStateException();
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      Object k = current.key;
      current = null;
      HashMap.this.removeEntryForKey(k);
      expectedModCount = modCount;
    }
  }

As can be seen from the above code, when an iterator is initially given mCount of the object calling the iterator, how can an exception be thrown once the object's mcount is found to be different from the mcount stored in the iterator during the iterator traversal

Ok, here's the full explanation of this

Fail - Fast mechanism

We know that ES34en.util.HashMap is not thread-safe, so if another thread modifies map while using the iterator, it will throw ConcurrentModificationException, which is called the ES39en-ES40en policy. This 1 policy is implemented in the source code through the modCount field. modCount, as the name implies, is the number of changes. Any change to the HashMap content increases this value, which is then assigned to the iterator's expectedModCount during the initializer. During the iteration, determine if modCount is equal to expectedModCount, if not, it means that other threads have already modified Map: note that modCount is declared as volatile to ensure visibility of changes between threads.

It is recommended to use iterators when traversing non-thread-safe data structures

Thank you for reading, I hope to help you, thank you for your support to this site!


Related articles: