1

In a multi-thread module, I don't care whether it is thread-safely writing over a java.util.Collection (e.g. java.util.Set) object. What it does is removing some independent elements by multiple threads, which may perform removal on the same element at the same time. Then, what happens? That element is removed, or any exception is thrown?


Kejia

2
  • Thanks for answers. Yes, ConcurrentModificationException is thrown in my case. Instead of solving it with Collections.synchronized*, I now replace java.util.Set interface with java.util.concurrent.ConcurrentLinkedQueue, in case of much overhead---of course, I have to care about duplicate elements of it. Commented Mar 9, 2011 at 15:13
  • ConcurrentLinkedQueue has some specific use cases, but i doubt this is it. i'd use either the Collections.synchronizedSet() as mentioned below, or Collections.newSetFromMap(new ConcurrentHashMap()). Commented Mar 9, 2011 at 16:28

5 Answers 5

5

It is even possible that an ConcurrentModificationException is thrown, when you remove different objects. That depends on the implementation of the Set you are using: The remove() method may iterate over the set. Or worse: It may modifies some other internal variables and leave the set in an inconsistent state without throwing any exception.

There is a really easy solution:

Set safeSet = Collections.synchronizedSet(set);

You still need to pay attention if you want to iterate over it, as described in the apidoc: http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedSet%28java.util.Set%29 but all the other methods (including remove) are fine.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the guide. Yes, ConcurrentModificationException is thrown in my case. Instead of solving it with Collections.synchronized*, I now replace java.util.Set interface with java.util.concurrent.ConcurrentLinkedQueue, in case of overhead thoughts---of course, I have to care about duplicate elements of it.
2

The results are unpredictable. The internal structure of the Set may be left in an inconsistent and unusable state.

Comments

2

'ConcurrentModificationException' if you are lucky. Chaos if not. Either use Collections.synchronized* or synchronize on some other object, don't do this.

Comments

2

java.util.Set is only an interface. The behaviour depends on the implementation of the Set interface. You must not access a HashSet with multiple threads as the behaviour is not guaranteed, although it is likely to throw ConcurrentModificationException if you do this.

Comments

1

You might not care, because you think that the Set would retain its integrity if you do something like that. But it won't.

You either need Collections.newSetFromMap(new ConcurrentHashMap<E, Boolean>()); or to use some syncronization. Removal isn't the only problem here. You could also end up with duplicates in the Set or who knows what else if you just use a HashSet.

Given a proper Set implementation designed to handle threading issues, then one thread will remove the item and the other will find the item not there, which can be determined by the return value of the remove method on the Set.

Note that if you are iterating over the set, you have to use some external synchronization if you are removing elements during the iteration.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.