Deepanshu Arora
Deepanshu Arora

Reputation: 435

Is values() of ConcurrentHashMap thread safe?

I'm new to Java8 and working on a problem where multiple threads (~10) are writing values to a Concurrent Hash Map. I have another dedicated thread which reads all the values present in Concurrent Hash Map and returns them (every 30 seconds). Is iterating over result of values() method the recommended way of fetching results without getting Concurrent Modification Exception?

Note: I am perfectly fine with getting stale data

I went over the official docs which says:

Retrieval operations generally do not block, so may overlap with update operations . Retrievals reflect the results of the most recently completed update operations holding upon their onset. 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 doc of values() method says:

Returns a Collection view of the values contained in this map

Is the below code thread safe?

for (String name: myMap.values()) {
     System.out.println("name": + name);
}

Upvotes: 2

Views: 1404

Answers (1)

Stephen C
Stephen C

Reputation: 719229

Is iterating over result of values() method the recommended way of fetching results without getting a ConcurrentModificationException?

Yes. It is the recommended way, and you won't get a ConcurrentModificationException.

As the package level javadoc states:

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.

Is the below code thread safe?

  for (String name: myMap.values()) {
       System.out.println("name": + name); 
  }

Yes ... with some qualifications.

Thread safety really means that the code works according to its specified behavior in a multi-threaded application. The problem is that you haven't said clearly what you expect the code to actually do.

What we can say is the following:

  1. The iteration will see values as per the previously stated guarantees.
  2. The memory model guarantees mean that there shouldn't be any nasty behavior with stale values ... unless you mutate value objects after putting them into the map. (If you do that, then the object's methods need to be implemented to cope with that; e.g. they may need to be synchronized. This is moot for String values, since they are immutable.)

Upvotes: 3

Related Questions