I want to implement a bean where I have a TreeSet
that is storing integers in sorted order. The only methods that use this TreeSet
are addValue
that is adding a new integer to the set, and getHighestValue
that is returning the last value in the set using the method last()
from SortedSet
.
Is there any concurrency issue here? I'm not using any explicit iterator so there shouldn't be any concurrency problem when fetching the highest value but I don't know if last method can throw any ConcurrentModificationException
or any other exception if two threads try to add and get the highest value at the same time.
Yes, assuming multiple threads are interacting with the set, and at least one is modifying, there are concurrency concerns. In particular, you mention multiple threads doing the add operation, which is definitely going to cause problems - worse however, they may not raise ConcurrentModificationException
s.
The purpose of ConcurrentModificationException
is to alert you to clearly erroneous concurrency issues, such as attempting to remove an item from a collection as you iterate over it (it's unclear what the collection should even do, in such a case). However the exception can only be raised when the collection is aware of the erroneous modification. Since the collection is not thread-safe it explicitly does not guarantee multi-threaded operations will be done correctly, and you are expected to take care of manually protecting the collection yourself.
The easiest, though least efficient, way to do this is to wrap the set with Collections.synchronizedSortedSet()
before using it, i.e.:
SortedSet synchronizedSet = Collections.synchronizedSortedSet(new TreeSet());
This ensures that each method call will be done in serial, that is to say they will block waiting for any earlier calls to finish. However as such, you essentially lose most of the benefits of multi-threading.
Another alternative is to use an explicitly thread-safe SortedSet
, namely ConcurrentSkipListSet
:
This implementation provides expected average
log(n)
time cost for thecontains
,add
, andremove
operations and their variants. Insertion, removal, and access operations safely execute concurrently by multiple threads.
This implementation allows you to interact with the set from multiple threads without further concern. That isn't to say it is the best way to implement the behavior you're looking for, but given what you've described - add and access the maximum value in a sorted set from multiple threads - it's what you're looking for.
See also: When is a ConcurrentSkipListSet useful?