2

I have an EnumSet which is final and immutable i.e. initialized once in the constructor.

Is the contains() method on this EnumSet thread safe? It is internally using an iterator to make the contains check. Hence if two threads are simultaneously calling the contains() can the iterator position in one call effect other one? Or are the iterators having different instances in these two thread calls?

Pokechu22
  • 4,984
  • 9
  • 37
  • 62
Harish
  • 7,589
  • 10
  • 36
  • 47

2 Answers2

1

The contents of an EnumSet can be changed despite the reference to it being final. No EnumSet is immutable. You can, however, wrap your EnumSet via Collections.unmodifiableSet(). If you also avoid retaining any reference to the original EnumSet then the unmodifiable wrapper object is functionally immutable.

Mutability notwithstanding, two iterators operating over the same Set at the same time presents no problem as long as the Set is not modified. This isn't really any different from the case of just one iterator.

In any case, the contains() method of an EnumSet likely doesn't create or use an iterator. The class implements membership via a bit vector, so it uses bit operations to perform the contains() test.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
0

No, if two threads call contains() at the same time, that will call iterator() twice which will create two separate iterators.

If you were trying to share an iterator between two threads, that would not be a good idea.

Note that if you modify the set in one thread while iterating over it (e.g. via contains) in another, then this bit of the docs comes into play:

The returned iterator is weakly consistent: it will never throw ConcurrentModificationException and it may or may not show the effects of any modifications to the set that occur while the iteration is in progress.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194