2016-09-14 14 views
3

私はメインメソッド内のforループを入力するコードがあります。私のjava.util.ConcurrentModificationExceptionの原因を見つけることができません

for (List<Point2D> points : output) { 
    currentPath = pathDistance(points); 
    if (shortest == 0){ 
     shortest = currentPath; 
    } else if (currentPath < shortest) { 
     best = points; 
     shortest = currentPath; 
    } 
} 
pathDistance

public static Double pathDistance(List<Point2D> path){ 
    double distance = 0; 
    int count = path.size()-1; 

    for (int i = 0; i < count; i++) { 
     distance = distance + path.get(i).distance(path.get(i+1)); 
    } 

    distance = distance + path.get(0).distance(path.get(count)); 
    return distance; 
} 

として定義されて

しかし、私はエラー

を得続ける
Exception in thread "main" java.util.ConcurrentModificationException 
    at java.util.SubList.checkForComodification(Unknown Source) 
    at java.util.SubList.size(Unknown Source) 
    at java.util.Collections$SynchronizedCollection.size(Unknown Source) 
    at TSMain.pathDistance(TSMain.java:76) 
    at TSMain.main(TSMain.java:203) 

私は、これは、反復が依存しながら、私は、オブジェクトを変更することだということを意味することになっている知っていますそれは起こっているかもしれないが、私の人生は分からない。どんな助けもありがとう。

+2

あなたは 'output'を変更していますが、必ずしもこの' for'ループで変更する必要はありません。これは、別のコードの別のスレッドでも実行できますが、 'output'オブジェクトとまったく同じです。 – Tom

+0

強化されたforループを、各反復でサイズを計算する従来の方法に置き換えてください。リストをまったく変更する(要素を削除するか要素を追加する)場合、拡張forループの問題が発生します。 –

+2

'Collections.synchronizedCollection'でラップされたサブリストを渡しているようです。しかし、元のリストは、反復処理中に変更されています。 – vsminkov

答えて

1

あなたのスタックトレースは、コードsubListのどこかが(直接的または間接的に)Collections.synchronizedCollectionに渡されることを示しています。このように

Set<List<Point2D>> output = Collections.singleton(
    Collections.synchronizedCollection(data.subList(start, end))); 

ただし、dataのリストはコピーされません。そしてpoints subListはまだdataリストの範囲を指しています。 オリジナルリストはmomet path.size()コールが発生すると変更されます。

あなたは簡単に、私はまた、あなたのコード内の同期に問題があるように見えることに気づくはずですpathDistance

for(List<Point2D> points : output){ 
    List<Point2D> pointsCopy = new ArrayList<>(points) 
    currentPath = pathDistance(pointsCopy); 
    // rest of code using pointsCopy 
} 

に渡す前に、明示的なリストのコピーをすることによって、あなたの問題を解決することができます。サブリストを同期コレクションにラップすることは悪い考えです。なぜなら、元のリストは適切な同期を取って安全でない方法で変更できるからです。

リスト修正チェックの詳細については、AbstractList#modCountソースを参照してください。

関連する問題