Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is there any Concurrent LinkedHashSet in JDK6.0 or other libraries?

my code throw follow exception:

java.util.ConcurrentModificationException
        at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
        at java.util.LinkedList$ListItr.next(LinkedList.java:696)
        at java.util.AbstractCollection.addAll(AbstractCollection.java:305)
        at java.util.LinkedHashSet.<init>(LinkedHashSet.java:152)
        ...

I want a ConcurrentLinkedHashSet to fix it,

but I only found ConcurrentSkipListSet in java.util.concurrent,this is TreeSet, not LinkedHashSet

any easies way to get ConcurrentLinkedHashSet in JDK6.0?

thanks for help :)

like image 465
Koerr Avatar asked Mar 13 '11 16:03

Koerr


2 Answers

A ConcurrentModificationException has nothing to do with concurrency in the form you're thinking of. This just means that while iterating over the Collection, someone (probably your own code - that happens often enough ;) ) is changing it, i.e. adding/removing some values.

Make sure you're using the Iterator to remove values from the collection and not the collection itself.

Edit: If really another thread is accessing the Collection at the same time, the weak synchronization you get from the standard library is useless anyhow, since you've got to block the Collection for the whole duration of the operation not just for one add/remove! I.e. something like

synchronize(collection) {
   // do stuff here
}
like image 184
Voo Avatar answered Sep 21 '22 08:09

Voo


You can always create a synchronized collection with Collections.synchronizedMap(myMap);. However, trying to alter the map while you're iterating (which I'm assuming is the cause of your error) will still be a problem.

From the docs for synchronizedMap:

Returns a synchronized (thread-safe) map backed by the specified map. In order to guarantee serial access, it is critical that all access to the backing map is accomplished through the returned map.

It is imperative that the user manually synchronize on the returned map when iterating over any of its collection views ... Failure to follow this advice may result in non-deterministic behavior.

This is because

  • normally a concurrent collection is really guaranteeing atomic get/put but is not locking the entire collection during iteration, which would be too slow. There's no concurrency guarantee over iteration, which is actually many operations against the map.

  • it's not really concurrency if you're altering during iteration, as it's impossible to determine correct behavior - for example, how do you reconcile your iterator returning hasNext == true with deleting a (possibly the next value) from the collection?

like image 42
Steve B. Avatar answered Sep 23 '22 08:09

Steve B.