Reputation: 176
I am getting the following java.util.ConcurrentModificationException
on this method
private AtomicReference<HashMap<String, Logger>> transactionLoggerMap = new AtomicReference<HashMap<String,Logger>>();
public void rolloutFile() {
// Get all the loggers and fire a temp log line.
Set<String> transactionLoggerSet = (Set<String>) transactionLoggerMap.get().keySet();
Iterator<String> transactionLoggerSetIter = transactionLoggerSet.iterator();
while(transactionLoggerSetIter.hasNext()){
String key = (String) transactionLoggerSetIter.next();
Logger txnLogger = transactionLoggerMap.get().get(key);
localLogger.trace("About to do timer task rollover:");
txnLogger.info(DataTransformerConstants.IGNORE_MESSAGE);
}
}
Please suggest, if I am using a Atomic Reference, how do i get a como?
Upvotes: 2
Views: 880
Reputation: 553
Remove the redundant
Set<String> transactionLoggerSet = (Set<String>) transactionLoggerMap.get().keySet();
You would still have to use synchronization as you are iterating over the map. SynchronizedMap guarentees consistency for its API methods. For the rest, you would need to do client side synchronization
Upvotes: 0
Reputation: 4704
Maybe you can consider iterating over a local copy of the collection instead of the same collection. It would be an easy way to ensure your collection will not be modified while you're looping over it. It is advisable to use immutable objects on a multi-threaded environment and you prevent this kind of problems for free.
Hope it helps.
Upvotes: 1
Reputation: 116938
A ConcurrentModificationException
means that you have modified the collection outside of the iterator. I don't see any modifications in your loop so I assume that there is another thread that is also adding or removing from the transactionLoggerMap
at the same time you are iterating across it.
Even though you have it wrapped in an AtomicReference
, you still cannot have two threads making changes to the same unsynchronized collection at the same time. AtomicReference
does not synchronize the object it is wrapping -- it just gives you a way to atomically get and set that reference.
You will need to make this a synchronized collection either by using the ConcurrentHashMap
class or wrapping your HashMap
using the Collections.synchronizedMap(map)
method.
Upvotes: 9
Reputation: 11899
Because you are not protecting against concurrent modifications during your iteration. The Atomic reference only makes sure you get your Map (and it's contents).
Upvotes: 1