【问题标题】:map ConcurrentModificationException in for header在标头中映射 ConcurrentModificationException
【发布时间】: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


【解决方案1】:

ConcurrentModificationException:

当这种修改是不允许的时,检测到对象的并发修改的方法可能会抛出此异常。

如果您在键/值的迭代过程中修改了Multimap 中的键/值,那么您将无法在修改后继续迭代(因此例外)。

考虑改用Multimaps.transformValues(Multimap, Function)

【讨论】:

  • 我不转换值 - 我把新的
  • @gstackoverflow put 是对多图的键/值(也称为整体)的修改。
猜你喜欢
  • 1970-01-01
  • 2017-06-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-04
  • 1970-01-01
  • 2015-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多