我想將一些串行代碼轉換成一些'很好'的多線程代碼,但是當我嘗試運行它時,我從迭代器的java.util.ConcurrentModificationException
獲得了我正在迭代的Set
中的200多個元素。我認爲如果你嘗試修改你想要訪問/迭代的東西,反之亦然,你只能得到這個異常,但我沒有改變任何東西。即使我不編輯任何東西,爲什麼會得到ConcurrentModificationException?
的例子我談論遍歷一個TreeMap
的keySet
和代碼如下:
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
或必須更改簽名中的任何內容。
在此先感謝
編輯:完成的代碼,並添加調用方法以及
什麼是'S1'?請粘貼完整代碼 – fge
可能的解決方案:在run()中使用映射的副本(例如ImmutableMap.copyOf(S))。 – ZhekaKozlov
這可能不會解決你的問題,但是你可以使用'ExecutorCompletionService'來跟蹤所有提交的'Future'對象,因爲你不需要自己維護一個數組。 – isnot2bad