I'm using following construct for creating a threadsafe Map
.
Collections.synchronizedMap(new LinkedHashMap());
Though I'm getting ConcurrentModificationException
error.
1 Answer. ConcurrentHashMap is designed for concurrency and improves performance while Collections. synchronizedMap(map) which is non-synchronized by sort can be synchronized by applying a wrapper using Collections.
SynchronizedMap and ConcurrentHashMap are both thread safe class and can be used in multithreaded application, the main difference between them is regarding how they achieve thread safety.
A synchronized resource can be accessed by only one thread at a time. HashMap can be synchronized using the Collections. synchronizedMap() method. The synchronizedMap() method of java.
ConcurrentHashMap allows performing concurrent read and write operation. Hence, performance is relatively better than the Synchronized Map. In Synchronized HashMap, multiple threads can not access the map concurrently. Hence, the performance is relatively less than the ConcurrentHashMap.
Without code it is hard to guess what is the real issue, but my guess is, you are not using returned collection to perform operations. As per javadoc
In order to guarantee serial access, it is critical that all access to the backing collection is accomplished through the returned collection. It is imperative that the user manually synchronize on the returned collection when iterating over it:
Collection c = Collections.synchronizedCollection(myCollection);
...
synchronized(c) {
Iterator i = c.iterator(); // Must be in the synchronized block
while (i.hasNext())
foo(i.next());
}
Failure to follow this advice may result in non-deterministic behavior.
Not to detract from any of the other answers here, but this code below shows that concurrent modification has little to do with actual multithreading. It's caused when you say, iterate over a collection but modify it while you are iterating....
List list = new ArrayList();
list.add("1");
list.add("2");
Iterator i = list.iterator();
while (i.hasNext()) {
Object value = i.next(); // throws java.util.ConcurrentModificationException
list.add("another");
}
Long story short, the solution to not get a ConcurrentModificationException
in your code would be using a ConcurrentHashMap
instead of Collections.synchronizedMap(new LinkedHashMap());
. Explanation here:
As Nambari says, the problem is harder to identify without actual code. Note that this Map
only protects the objects that contains. Still, you can modify a same object instance in a method:
Map<String, Object> map = new ConcurrentHashMap<String, Object();
//fill the map...
map.put("data", new Data());
//and now we have this unsynchronized method that two or more threads can access at the same time
public void modifyData(String key, int newDataIntValue) {
//this is synchronized by the ConcurrentHashMap
Data data = map.get(key);
//this isn't
//you can get problems here...
data.setIntValue(newDataIntValue);
}
The synchronized collection won't save your code for these cases. You should synchronize this method by yourself.
Additional info: if you're trying to implement a cache library or the Flyweight design pattern, don't reinvent the wheel and use a proven and tested framework like ehcache or jboss cache.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With