質問
マルチスレッドの申請ようにして見 ConcurrentModificationExceptions
当社のリスト(主 ArrayList
, もベクトル.ある時と思うの同時変更が起こっているのかが繰り返し処理の回収が足りない事項、例外はスローされます。私のドキュメントのための ConcurrentModificationException
とができないものの、どういったりすることを私は同時に変更です。とラッピング毎にアクセスでコレクションに同期ブロックを防ぐ方法はありですか?
更新: はい、知って Collections.synchronizedCollection
, などの防人の修正の収集にありながら繰り返し処理します。と思う少なくとも私の問題が起きているのが誰かに追加しいコレクションを繰り返し処理します。
二回目の更新 自分がその気にさえなればいを組み合わせについても言synchronizedCollection、クローニングのようにJasonたものを、java.util.同時に、apacheコフレームワークからのjacekfooとJavamannかったんで受け入れの答えです。
解決
オリジナルの問いうか序で繰り返し処理する反復子はライブの更新の回収が残りのスレッドセーフです。これは非常に高価な問題の解決に一般の場合、その標準コレクションクラスです。
多くの方の達成の部分的なソリューションの問題、お申し込みのひとつに数えられるものだしれない。
Jasonを 特定することでスレッドの安全性を回避するためにはConcurrentModificationExceptionを投げる, ものロ.
Javamannつ 二つの特定の授業 の java.util.concurrent
パッケージを解決するのと同じ問題がロックでは、スケーラビリティが重要です。これだけ出荷されJava5がされている多様なプロジェクトのbackportの機能をパッケージに以前のJavaのバージョンを含む この, かんなパフォーマンスの良好な前Jre.
でご使用の場合は、Apache Commons、図書館としてjacekfoo 指摘, は、 apache collections framework 含まれである。
他のヒント
によって更新頻度は私の最も気に入ったものの一つであるCopyOnWriteArrayListはCopyOnWriteArraySet.彼らは新しいリスト/トの更新な兼職の状況変更します。
チェック java.util.兼職の状況 のためのバージョンの標準の収れている工学的取扱い並行処理です。
ありきの同期アクセスは、コレクションオブジェクト。
使用でき、同封の周辺の既存のオブジェクトです。見 ョンにします。synchronizedCollection().例えば:
List<String> safeList = Collections.synchronizedList( originalList );
しかしながらすべてのコードを使う必要があり、安全なバージョンで繰り返し処理が別のスレッドに変更します。
解決のための繰り返しの問題、コピーのリストです。例:
for ( String el : safeList.clone() )
{ ... }
より最適化し、スレッドセーコレクション、レジリエント工学"の分野にも java.util.兼職の状況.
通常でき、ConcurrentModificationExceptionねば削除の要素をリストからなって反復。
最も簡単な方法を試験す:
List<Blah> list = new ArrayList<Blah>();
for (Blah blah : list) {
list.remove(blah); // will throw the exception
}
んかんであるといわれている。すためにはご自身のスレッドセーリストで使ったりすることをコピー元のリストを書き込みと同期したクラスに書き込みます。
きみを守りの複製と修正を List
なには影響します。
包装へのアクセスでコレクションに同期ブロックは正しい関係ではないかと思います。プログラミングの練習を手腕のある種のロック機構(セマフォ、ミューテックス等)の処理時状態にするのではなく、複数のスレッド)。
によってはご利用の場合ことができることは通常、一部の最適化のみロックの場合があります。たとえば、コレクションの頻度で読んで書くことができますを同時に読み込みが強のロックの場合に書き込みが進んでいます。同時に読み込みのみ反の場合には、変更されます。
ConcurrentModificationExceptionが最善の努力を払った上でこのお聞こうとしているのですが、ハードの問題です。ありません良いことを確実に優れたデバイス特性を維持するとともにアクセスパターンのない同時に変更します。
同期が防止の同時変更することができますかーリゾートの終了が可能であり、これまでのようになって多額のコストがかかります。の最善のことはすでに考えら約アルゴリズムです。できない場合はただのロック-無料溶液に、そのリゾートに同期します。
参照を実施します。基本的に店舗int:
transient volatile int modCount;
ることを忘れがある場合は構造改'(のように削除).場の反復子を検出することmodCount変更ですの同時修正ます。
同期(ョンにします。synchronizedXXX思いから保障するものではありませんので反復子の安全性でのみ同期に書き込みや読み込みによせ、セット---
Java.util.concurennt、apacheのcollections frameworkでは、授業による最適な仕事で正しく並行環境があり読み取るunsynchronized)より書き込み見FastHashMap.
また同期間iteratinsの一覧です。
List<String> safeList = Collections.synchronizedList( originalList );
public void doSomething() {
synchronized(safeList){
for(String s : safeList){
System.out.println(s);
}
}
}
このロックのリストに同期化ブロックすべてのスレッドがアクセスのリストを編集することは繰り返し処理を実行します。の下振れは、自分の好きな名前を付けてボトルネックです。
このメモリを超えます。clone()メソッドが速くようにやっているの繰り返し...
ョンにします。synchronizedList() ラーニングによるリストを名目的にはドは、java.util.兼職の状況はより強力な特徴です。
これにより、その同時修正ます。んで語りの効率が)
List<Blah> list = fillMyList();
List<Blah> temp = new ArrayList<Blah>();
for (Blah blah : list) {
//list.remove(blah); would throw the exception
temp.add(blah);
}
list.removeAll(temp);