为什么即使我不编辑任何内容,我也会得到一个ConcurrentModificationException



我正在尝试将一些串行代码转换为一些"不错的"多线程代码,但是当我尝试运行它时,我从迭代Set中获得 200 多个元素的java.util.ConcurrentModificationException迭代器。我以为只有当您尝试修改您尝试访问/迭代的内容时,您才能获得此异常,反之亦然,但我没有更改任何内容。

我正在讨论的示例遍历TreeMapkeySet,代码如下所示:

private static SortedMap<BigInteger,Long> algorithm7(int n, 
        final SortedMap<BigInteger, Long> S, ExecutorService pool) {
    final SortedMap<BigInteger,Long> S1 = new TreeMap<BigInteger, Long>();
    final SmallAntiChain alfa = SmallAntiChain.universeAntiChain(n);
    final SmallAntiChain u = SmallAntiChain.universeAntiChain(n+1);
    final SmallAntiChain l = SmallAntiChain.singletonAntiChain(n+1);
    Future<?>[] list = new Future[S.size()];
    int i = 0;
    for (final BigInteger tCode : S.keySet()) {
        list[i++] = pool.submit(new Runnable() {
            @Override
            public void run() {
                SmallAntiChain t = SmallAntiChain.decode(tCode);
                Set<int[]> rtsymm = (t.join(l)).symmetryGroup();
                SortedMap<BigInteger, Long> St = new TreeMap<BigInteger, Long>();
                for (SmallAntiChain x : new AntiChainInterval(t.join(l),u.omicron(t, alfa))) {
                    BigInteger b = x.standard(rtsymm).encode(); 
                    Storage.store(St, b);
                }
                for (BigInteger b : St.keySet()) {
                    SmallAntiChain x = SmallAntiChain.decode(b);
                    BigInteger code = x.standard().encode();
                    Storage.store(S1,code,St.get(b)*S.get(tCode));
                }
            }
        });
    }
    try {
        for(Future<?> f : list)
            f.get();
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
    return S1;
}

调用方法如下所示:

public static SortedMap<BigInteger, Long>[] equivalenceClasses(int till, ExecutorService... pools) throws SyntaxErrorException {
    if(pools.length < 1)
        pools = new ExecutorService[]{ Executors.newFixedThreadPool(1) };
    @SuppressWarnings("unchecked")
    SortedMap<BigInteger, Long>[] reS = new TreeMap[till+1];
    reS[0] = new TreeMap<BigInteger,Long>();
    Storage.store(reS[0],SmallAntiChain.emptyAntiChain().standard().encode());
    Storage.store(reS[0],SmallAntiChain.emptySetAntiChain().standard().encode());
    int n = 0;
    while (n < till) {
        reS[n+1] = algorithm7(n,reS[n], pools[0]);
        n++;
    }
    return reS;
}

谁能告诉我为什么我会得到异常以及我可以做些什么来解决这个问题?最好不必使用ConcurrentSkipListMap或更改签名中的任何内容。

提前致谢


编辑:完成代码并添加了调用方法

根据 Java 规范,如果SortedMap没有经过结构修改,get(..)不应该抛出ConcurrentModificationException。由于您尚未提供完整的代码,因此我唯一能建议的是在创建SortedMap后用Collections.unmodifiableSortedMap(S s)包装它。如果您错过了在结构上修改 Map 的代码,这将引发Exception

即使您提供的代码不修改SortedMap,这并不排除外部(方法外)线程不会修改它。

最新更新