15

Like the title says, i would like to get a thread-safe HashSet using Guava Collections.
Are any available?

Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
santiagobasulto
  • 11,320
  • 11
  • 64
  • 88
  • 4
    There would be no sense in making in threadsafe when it is already immutable, isn't it? – whiskeysierra Sep 02 '10 at 17:13
  • You're righy Willi. It will not be immutable. Several threads will mutate it concurrently. – santiagobasulto Sep 02 '10 at 17:21
  • 2
    By the way, don't prefer collections from Guava over JDK ones just because they're from Guava. Use each when they make the most sense for what you're doing. – ColinD Sep 02 '10 at 17:25
  • @Colin: Totally agree, and in fact, my answer doesn't use any Guava classes at all, just what comes with the Java Concurrency Framework. :-P – C. K. Young Sep 02 '10 at 17:29
  • @CollinD: Yeah, that's absolutely true. But i know well the java.util and java.concurrent collections. I've a hard program running and was trying to test the Guava Collections. – santiagobasulto Sep 02 '10 at 17:30
  • @santiago: If you really want to watch Guava shine, try the `Multimap` and `Multiset`, and the soft/weak keys/values with `MapMaker`. :-) (There are of course many other features, too many for me to cover.) – C. K. Young Sep 02 '10 at 17:39
  • I've used this soft referenced map in a cache system and works real well new MapMaker().softKeys().makeMap() – santiagobasulto Sep 02 '10 at 17:41
  • @whiskeysierra: Never assume a "de facto" immutable class to be thread-safe. Such a class is not protected against memory visibility and code reordering issues and therefore it is NOT thread-safe. – 30thh Mar 10 '18 at 10:36
  • @30thh What's the point in having and using an immutable class if I can't rely on it? – whiskeysierra Mar 12 '18 at 08:18
  • @whiskeysierra immutability has in general nothing to do with tread-safety. Only simple immutable objects with all the fields declared as final are guaranteed thread-safe. Please google for "JMM Safe Initialization". – 30thh Mar 12 '18 at 10:00

4 Answers4

28
Set<K> set = Collections.newSetFromMap(new ConcurrentHashMap<K, Boolean>());
C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • 1
    Btw, all your points belong to me as i answered this question on the guava mailing list, 8 minutes before it was posted here ;) – whiskeysierra Sep 02 '10 at 17:20
  • @Willi: If I could assign them to you, I would, because I've already hit my rep cap for the day, so I'm getting absolutely no rep for this answer. :-P – C. K. Young Sep 02 '10 at 17:21
  • 2
    You'd think there'd be a little bit more straightforward way of doing this. – ColinD Sep 02 '10 at 17:24
  • 1
    @Colin: Welcome to Java! If you want straightforward, code in Ruby or Scheme. :-P – C. K. Young Sep 02 '10 at 17:26
  • @Colin: it may seem like a monster code. But once you get in the API and familiarize with it, you get amazed how simple it get. It happened to me with the Streams Framework. – santiagobasulto Sep 02 '10 at 17:28
  • I'm pretty familiar with most core Java APIs, this trick just strikes me as particularly unintuitive as the best way to accomplish this. – ColinD Sep 02 '10 at 17:45
7

This would be the right answer, Using the Sets class from Guava. Anyway the answer from @crhis was good intended.

Sets.newSetFromMap(new ConcurrentHashMap<V, Boolean>());
santiagobasulto
  • 11,320
  • 11
  • 64
  • 88
  • Actually, this is now deprecated, currently `Collections.newSetFromMap(new ConcurrentHashMap());` should be used. – sarsonj Oct 15 '19 at 12:45
6

Java 8 introduces new way to create concurrent hash set - ConcurrentHashMap.newKeySet()

Set<K> set = ConcurrentHashMap.newKeySet();

It's shorter than wrapping in Collections.newSetFromMap

turbanoff
  • 2,439
  • 6
  • 42
  • 99
4

Google Collections had a factory method named Sets.newConcurrentHashSet() for a while.

Its implementation was similar to Chris's suggestion:

public static <E> Set<E> newConcurrentHashSet() {
  return newSetFromMap(new ConcurrentHashMap<E, Boolean>());
}

They had a newSetFromMap() method inside the com.google.common.collect.Sets class (written by Doug Lea with assistance from members of JCP JSR-166). That method was added to java.util.Collections in java 1.6.

It was withdrawn in Google Collections 1.0rc1, since there are plans to better support concurrent sets in Guava (more information here).

This post expands on the use of the "newSetFromMap" method to construct concurrent sets.

Community
  • 1
  • 1
Etienne Neveu
  • 12,604
  • 9
  • 36
  • 59
  • 1
    Google guava still has newConcurrentHashSet() method BTW. https://google.github.io/guava/releases/27.0-jre/api/docs/com/google/common/collect/Sets.html#newConcurrentHashSet-- – turbanoff Nov 02 '18 at 13:26