一、フェイルファスト(fail—fast)

イテレータでコレクションオブジェクトを走査する際、走査中にコレクションオブジェクトの内容を変更(追加、削除、変更)すると、Concurrent Modification Exception がスローされます。

原理:イテレータは走査時にコレクション内の内容に直接アクセスし、走査中に modCount 変数を使用します。コレクションが走査されている間に内容が変更されると、modCount の値が変わります。イテレータが hashNext()/next() で次の要素を走査する前に、modCount 変数が expectedmodCount 値と一致するかどうかを毎回チェックし、一致すれば走査を続行します。そうでなければ例外をスローして走査を終了します。

注意:ここで例外がスローされる条件は、modCount != expectedmodCountこの条件が検出された場合です。コレクションが変更されたときに modCount の値が偶然 expectedmodCount 値にも設定された場合は、例外はスローされません。したがって、この例外がスローされるかどうかに依存して並行操作をプログラミングすることはできません。この例外は並行変更のバグを検出するためにのみ使用することをお勧めします。

シナリオ:java.util パッケージのコレクションクラスはすべてフェイルファストであり、マルチスレッド下での並行変更(イテレーション中に変更されること)はできません。

二、フェイルセーフ(fail—safe)

フェイルセーフ機構を採用したコレクションコンテナは、走査時にコレクションの内容に直接アクセスするのではなく、まず元のコレクションの内容をコピーし、コピーしたコレクション上で走査を行います。

原理:イテレーション時は元のコレクションのコピーを走査するため、走査中に元のコレクションに対して行われた変更はイテレータには検出されず、Concurrent Modification Exception は発生しません。

> 欠点:コピー内容に基づく利点は Concurrent Modification Exception を回避できることですが、同様に、イテレータは変更後の内容にアクセスできません。つまり、イテレータが走査するのは走査開始時点で取得したコレクションのコピーであり、走査中に元のコレクションで発生した変更はイテレータには認識されません。

シナリオ:java.util.concurrent パッケージのコンテナはすべてフェイルセーフであり、マルチスレッド下で並行使用・並行変更ができます。

原文アドレス:http://www.cnblogs.com/ygj0930/p/6543350.html