JDK-6625725 : (coll) modCount should not be volatile
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:collections
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-11-04
  • Updated: 2012-10-08
  • Resolved: 2011-05-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availabitlity Release.

To download the current JDK release, click here.
7 b25Fixed
Collections use a modCount field to track changes to data structures,
so they can throw ConcurrentModificationException if another thread
unexpectedly modifies the collection (rather than corrupting the data
and carrying on).

Some collections mark modCount as volatile; some do not.
Since the modCount mechanism comes with no guarantees, and users of
single-threaded collections do not expect to pay the (high) price
of a volatile write on every modification operation, the volatile
modifier should be removed.

Here are the uses of volatile to be removed:

./java/util/HashMap.java:177:    transient volatile int modCount;
./java/util/IdentityHashMap.java:176:    private transient volatile int modCount;
./java/util/WeakHashMap.java:185:    volatile int modCount;

EVALUATION Here's the obvious patch: diff --git a/src/share/classes/java/util/HashMap.java b/src/share/classes/java/util/HashMap.java --- a/src/share/classes/java/util/HashMap.java +++ b/src/share/classes/java/util/HashMap.java @@ -173,7 +173,7 @@ public class HashMap<K,V> * rehash). This field is used to make iterators on Collection-views of * the HashMap fail-fast. (See ConcurrentModificationException). */ - transient volatile int modCount; + transient int modCount; /** * Constructs an empty <tt>HashMap</tt> with the specified initial diff --git a/src/share/classes/java/util/IdentityHashMap.java b/src/share/classes/java/util/IdentityHashMap.java --- a/src/share/classes/java/util/IdentityHashMap.java +++ b/src/share/classes/java/util/IdentityHashMap.java @@ -173,7 +173,7 @@ public class IdentityHashMap<K,V> /** * The number of modifications, to support fast-fail iterators */ - private transient volatile int modCount; + private transient int modCount; /** * The next size value at which to resize (capacity * load factor). diff --git a/src/share/classes/java/util/WeakHashMap.java b/src/share/classes/java/util/WeakHashMap.java --- a/src/share/classes/java/util/WeakHashMap.java +++ b/src/share/classes/java/util/WeakHashMap.java @@ -181,7 +181,7 @@ public class WeakHashMap<K,V> * * @see ConcurrentModificationException */ - volatile int modCount; + int modCount; @SuppressWarnings("unchecked") private Entry<K,V>[] newTable(int n) {