Martin Buchholz martinrb at
Wed Dec 11 18:48:36 UTC 2013

Alright, it's true that the "Concurrent" prefix of ConcurrentMap's name is
a strong hint that implementing classes are expected to be "concurrent" as
defined in the package javadoc.  But if we are serious about that, we
should at least add some guidance to the javadoc for the interface itself,
as we recently did for null handling.  Even the jdk7 version of
ConcurrentMap had methods that access multiple entries, if you count
methods inherited from Map.  But even in jdk8, with the addition of forEach
and replaceAll, there is no discussion of weak consistency and CME.

I see that Hashtable.forEach is synchronized.  This seems obligatory, given
the risk of CME, but it's not reflected in the documentation!  That should
be fixed - users need to know!

On Tue, Dec 10, 2013 at 11:25 AM, Doug Lea <dl at> wrote:

> On 12/10/2013 01:15 PM, Martin Buchholz wrote:
>> Perhaps Doug could provide history on the intent of ConcurrentMap.
> See the package-level docs in java.util.concurrent that compare
> Hashtable to ConcurrentMap, implying that it might not be a good idea
> to now retrospectively declare Hashtable as a ConcurrentMap even though,
> through the magic of defaults, they share methods.
> Pasting...
> The "Concurrent" prefix used with some classes in this package is a
> shorthand indicating several differences from similar "synchronized"
> classes. For example java.util.Hashtable and Collections.synchronizedMap(new
> HashMap()) are synchronized. But ConcurrentHashMap is "concurrent". A
> concurrent collection is thread-safe, but not governed by a single
> exclusion lock. In the particular case of ConcurrentHashMap, it safely
> permits any number of concurrent reads as well as a tunable number of
> concurrent writes. "Synchronized" classes can be useful when you need to
> prevent all access to a collection via a single lock, at the expense of
> poorer scalability. In other cases in which multiple threads are expected
> to access a common collection, "concurrent" versions are normally
> preferable. And unsynchronized collections are preferable when either
> collections are unshared, or are accessible only when holding other locks.
> Most concurrent Collection implementations (including most Queues) also
> differ from the usual java.util conventions in that their Iterators and
> Spliterators provide weakly consistent rather than fast-fail traversal:
>     they may proceed concurrently with other operations
>     they will never throw ConcurrentModificationException
>     they are guaranteed to traverse elements as they existed upon
> construction exactly once, and may (but are not guaranteed to) reflect any
> modifications subsequent to construction.

More information about the core-libs-dev mailing list