问题
I have the following code:
private Multimap<Object, ComplexCalcStrategy> strategies = HashMultimap.create();
....
Collection<ComplexCalcStrategy> strategiesThatNeedUpdating = strategies.get(mktDataChange.getOptionId());
for (ComplexCalcStrategy strategy : strategiesThatNeedUpdating) { //row number 88
updateMarketData(strategy.getStrategy(), mktDataChange);
}
and in logs I see following trace:
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
at java.util.HashMap$KeyIterator.next(HashMap.java:828)
at com.google.common.collect.AbstractMapBasedMultimap$WrappedCollection$WrappedIterator.next(AbstractMapBasedMultimap.java:486)
at package.ClassName.processMarketDataChange(ClassName.java:88)
I don't understand how does this code can produce CME.
Please, share your ideas.
P.S.
map fills here:
@Override
public void registerStrategy(final ComplexCalcStrategy strategy) {
for (Integer optionId : strategy.getOptions()) {
strategies.put(optionId, strategy);
}
if (strategy.getStrategy().tiedToStock) {
strategies.put(strategy.getUnderlying(), strategy);
}
....
}
This method invokes in another thread and looks like sometime iteration and map filling happens simultaneously and it is root cause.
I understand that I can use synchronized version of multimap.
Will it fix issue?
Is there nicer way?
回答1:
ConcurrentModificationException:
This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
If you modify the keys/values in a Multimap
during iteration of the keys/values then you cannot continue iterating after the modification (hence the exception).
Consider using Multimaps.transformValues(Multimap, Function) instead.
来源:https://stackoverflow.com/questions/36228084/map-concurrentmodificationexception-in-for-header