2011-01-11 2 views
1

リストまたはマップを反復処理するためのコードシーケンスは、ConcurrentModificationExceptionを防止しますか?私たちはコード内で繰り返して散発的なConcurrentModificationExceptionを持っています。問題の原因は2つあります。Javaでの散発的なConcurrentModificationExceptionを防ぐベストプラクティスは何ですか?

  1. 別のスレッド変化
  2. リストを変更してループ内で呼び出されるメソッドを反復のリスト。

問題1は、ループの周りで同期して解決することができます。しかし、原因2のようにループ内でエイリアンコードが呼び出された場合、これは悪いことです。

問題2は、リストまたはマップのコピーで解決できます。

これは、リストまたはマップが、ループの前に同期ブロックにコピーされている必要があることを意味します。より良い解決策がありますか?

いくつかのサンプルコード:

public void todoSomeThings(Map<Abc, Object> map){ 
    for(Abc abc : map.keySet()){ 
     abc.todoSomeThings(); 
    } 
} 

答えて

3

公正警告:juc(java.util.concurrentの)を使用してなど、誤差を除去しますが、あなたはおそらく最悪の場合に実行されます、つまりレースのアップデート、古い読み込みのベストプラクティスが

あなたを知っていますデータ構造、使用状態...、または少なくとも(それは最良ではない)ロックを使用します。

7

はあなたがjava.util.concurrentで同時コレクションを使用して考えがありますか?正直言って、それよりはるかに良いアドバイスをするのは難しいです...詳細が必要です。

注目すべき点は、スレッド間で変更可能なコレクションが共有され、反復処理中に何が突然変異している可能性があるかわからないコードの多くにさらされた可変コレクションがある場合、 可能であれば、デザインを変更することを検討してください。変更不能なコレクションは、しばしば、よりクリーンなものにすることができます。彼らは最初から作業するのが難しいかもしれませんが、後であなたのコードについて簡単に理由を見つけるのが容易になるでしょう。

+0

ほとんどの場合、パラメータであるためリストまたはマップのタイプを変更することはできません。 – Horcrux7

+0

@ Horcrux7:メソッドが(ArrayListの代わりに 'List'のように)できるだけ一般的な引数として取るべき理由を示す素晴らしい例です。 –

関連する問題