wood burning stoves*
The moose likes Threads and Synchronization and the fly likes Is HashMap.KeySet() thread safe ? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Is HashMap.KeySet() thread safe ?" Watch "Is HashMap.KeySet() thread safe ?" New topic
Author

Is HashMap.KeySet() thread safe ?

Nilesh Raje
Ranch Hand

Joined: Aug 02, 2005
Posts: 153
Hi Friends ,


In this code


is keyset thread safe? I believe this is more prone to concurrent modification exception as the keyset will hold the snapshot of the key and values in the memory and in the mean while if data is changed underlying by other thread then we will get concurrent modification exception.

here i have used synchronized on the method but which takes a lock on the Test Object .
Though i have synchronized the method I believe right way here to synchronize the whole map hence I feel this code is a serious problem.

Please correct me if i am wrong.

[Nitesh: Added code tags.]

Thanks and Regards,<br />Nilesh<br />SCJP 1.4, SCWCD 1.4
Nitesh Kant
Bartender

Joined: Feb 25, 2007
Posts: 1638

This is more suited for Threads & Synchronization forum. Moving it there.
Please CarefullyChooseOneForum for posting.


apigee, a better way to API!
Nitesh Kant
Bartender

Joined: Feb 25, 2007
Posts: 1638

Your question here is "Whether HashMap.KeySet() is thread safe"

This essentially can mean two things:

  • The call to method KeySet() is thread-safe?
  • The set returned from KeySet() method is thread-safe.


  • Synchronization of the method getAllWords() in your code, makes the method call KeySet() as thread-safe. Of course if and only if, from no where in the code does anybody calls the method HashMap.KeySet() directly.

    However, it does not in any way guarantee that the Set returned becomes thread safe. If you need to make it thread safe then you would have to take extra work. The bare minimum being to use Collections.synchronizedSet() method to wrap the returned set into a "nearly thread-safe" set. The reason for it being "nearly thread-safe" is that there are many cases as described in the javadoc where such sets breaks the thread-safety. The other way can be to use a concurrent set from the java concurrent package.
    Henry Wong
    author
    Sheriff

    Joined: Sep 28, 2004
    Posts: 18896
        
      40

    The bare minimum being to use Collections.synchronizedSet() method to wrap the returned set into a "nearly thread-safe" set. The reason for it being "nearly thread-safe" is that there are many cases as described in the javadoc where such sets breaks the thread-safety. The other way can be to use a concurrent set from the java concurrent package.


    The set that is returned from the map is backed by the map itself -- meaning wrapping it in a synchronizedSet() is definitely not enough. I would recommend using synchronizedMap on the private map variable instead. The keyset() method will return a set that is synchronized (no need to wrap again) -- and this keyset actually synchronizes on the same lock that the map uses. So, if the map is used at the same time as the returned set, no corruption occurs.

    The "cases as described in the javadoc where such sets breaks the thread-safety" are, of course, related to the iterators -- and the precautions specified in the JavaDocs still apply.

    Henry


    Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
    Billy Tsai
    Ranch Hand

    Joined: May 23, 2003
    Posts: 1304
    you can use ConcurrentHashpMap from Java 5 onward or use the following

    Map<KeyType, ValType> m =
    Collections.synchronizedMap(new HashMap<KeyType, ValType>());
    ...
    Set<KeyType> s = m.keySet();
    ...
    synchronized(m) {
    while (KeyType k : s)
    foo(k);
    }


    In the face of concurrent access, it is imperative that the programmer/developer/coder manually synchronize on the returned collection when iterating over it. The reason is that iteration is accomplished via multiple calls into the collection, which must be composed into a single atomic operation.

    BEA 8.1 Certified Administrator, IBM Certified Solution Developer For XML 1.1 and Related Technologies, SCJP, SCWCD, SCBCD, SCDJWS, SCJD, SCEA,
    Oracle Certified Master Java EE 5 Enterprise Architect
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Is HashMap.KeySet() thread safe ?