【发布时间】:2016-03-25 21:10:20
【问题描述】:
我有以下代码:
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);
}
在日志中我看到以下跟踪:
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)
我不明白这段代码如何产生 CME。
请分享你的想法。
附言
地图在这里填充:
@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);
}
....
}
此方法在另一个线程中调用,看起来有时迭代和地图填充同时发生,这是根本原因。
我知道我可以使用多地图的同步版本。
它会解决问题吗?
有更好的方法吗?
【问题讨论】:
-
你的 for 循环中发生了什么?
-
updateMarketData会发生什么? -
@gstackoverflow,它绝对很重要。这就是 ConcurrentModificationExceptions 的工作原理。
-
@gstackoverflow 是的,没错。没关系,您不会期望它出现在堆栈跟踪中,但这并不意味着
updateMarketData不会导致错误——如果您收到ConcurrentModificationException,则极有可能updateMarketData中的某些东西导致它即使updateMarketData没有出现在堆栈跟踪中。 -
这太复杂了,因为你的方法都调用了其他方法。您需要使用调试器来逐步完成此操作。在该方法调用的某处,您正在修改您正在迭代其键的 Map。
标签: java exception dictionary guava concurrentmodification