Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Concurrent modification exception in Map

 
Arun Raja S.K
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I am using a concurrent hashmap of structure Map<Set<Date>, Map<String, Object>> SampleMap.

The Map used inside the given map (Map"<"String, Object">") is also a concurrent hashmap,
but set is a only TreeSet type.

Still i get concurrent Modification exception when i add following line in logs,

logger.debug("sampleMap.keySet() + ". Size is " + sampleMap.keySet().size()"); and also in some other parts of same class dealing with this map.

This map is extensively used in Batch process by multiple threads to put and remove values in map and java version used is 1.5.

I think the exception is due to Treeset and also i find there is no similar implementation of concurrent handling collection for type Set.

It would be great if any one confirm whether my thinking over given issue is correct and also please suggest solution for this problem using java version 5 ?
 
Martin Vajsar
Sheriff
Posts: 3752
62
Chrome Netbeans IDE Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're using Set as a key? Uh oh.

I don't know where does the ConcurrentModificationException come from, but if it does come from the TreeSet you're using as a key, you have another, and more fundamental problem: you're using a mutable map key. Maps were not designed to work with keys whose values can change, so you need to modify your code so that the Set doesn't change once you put it inside the map.

Before you rush into wrapping the TreeSet into as an unmodifiable set (mind you, you must not keep any references on the original set, otherwise the unmodifiable protection can be compromised), I'd suggest to rethink why you're using Set as a key in the first place. If you let us know, perhaps somebody could come up with a better solution.
 
Arun Raja S.K
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This map is maintained in cache and the maximum size of set is 15. so the set in map is modified whenever latest date is found removing the old date of existing 15 dates. And also the map will always have only one key value pair ie (A key set containing 15 dates and map corresponding to that set.)
 
Martin Vajsar
Sheriff
Posts: 3752
62
Chrome Netbeans IDE Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You cannot use mutable keys with a map, regardless of the number of items you keep in the map. If a value of a key is about to change, you need to remove the old key and insert the new key to the map.

It looks to me you're using the map just as a convenient container to keep two disparate objects in. What you probably ought to do is to create a class which would keep your set and the "inner" map.

Perhaps if you tell us what does your cache look like (eg. which operations it supports), we could find something yet better.
 
K. Tsang
Bartender
Posts: 3526
16
Android Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is a bit weird. If you are indeed using a TreeSet (sorted Set<Date>) as you map key, how does your Map<String, Object> correspond to the correct order? Shouldn't your Map<String, Object> also need to be sorted like using a TreeMap?
 
Winston Gutkowski
Bartender
Pie
Posts: 10527
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Arun Raja S.K wrote:This map is maintained in cache and the maximum size of set is 15. so the set in map is modified whenever latest date is found removing the old date of existing 15 dates. And also the map will always have only one key value pair ie (A key set containing 15 dates and map corresponding to that set.)

Hunh? That sounds incredibly overengineered. If you simply want to maintain a cache of 15 dates, my suggestion would be to extend LinkedHashMap, and use its removeEldestEntry() method.

Winston
 
Arun Raja S.K
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, i will try implementing LinkedHashMap.
I also read that using lock over the set when we need to modify the set will also help to solve my problem.

// lock the collection
Map<String, Object> values = map.remove(key);
key = new TreeSet<String>(key);
// modify copy of key
map.put(key, values);
// unlock the collection.

Please suggest will above code solve my problem ?
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic