Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Is HashMap.KeySet() thread safe ?

 
Nilesh Raje
Ranch Hand
Posts: 153
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.]
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is more suited for Threads & Synchronization forum. Moving it there.
Please CarefullyChooseOneForum for posting.
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
    Marshal
    Pie
    Posts: 21404
    84
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    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
     
    Billy Tsai
    Ranch Hand
    Posts: 1304
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    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.
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic