Threadsafe way of exposing keySet()

Posted by Jake on Stack Overflow See other posts from Stack Overflow or by Jake
Published on 2011-01-17T02:35:07Z Indexed on 2011/01/17 5:53 UTC
Read the original article Hit count: 267

Filed under:
|

This must be a fairly common occurrence where I have a map and wish to thread-safely expose its key set:

public MyClass {
  Map<String,String> map = // ...
  public final Set<String> keys() {
     // returns key set
  }
}

Now, if my "map" is not thread-safe, this is not safe:

  public final Set<String> keys() {
     return map.keySet();
  }

And neither is:

  public final Set<String> keys() {
     return Collections.unmodifiableSet(map.keySet());
  }

So I need to create a copy, such as:

  public final Set<String> keys() {
     return new HashSet(map.keySet());
  }

However, this doesn't seem safe either because that constructor traverses the elements of the parameter and add()s them. So while this copying is going on, a ConcurrentModificationException can happen.

So then:

  public final Set<String> keys() {
     synchronized(map) {
       return new HashSet(map.keySet());
     }
  }

seems like the solution. Does this look right?

© Stack Overflow or respective owner

Related posts about java

Related posts about hashset