Java では、複数のスレッドがコレクション オブジェクトを同時に操作すると、ConcurrentModificationException 例外が発生することがあります。この例外は通常、コレクションの走査中に要素を変更または削除するときに発生し、コレクションの状態の不整合が発生します。したがって、例外がスローされます。この記事では、この例外の原因と解決策について詳しく説明します。
1. 例外の理由
通常、ConcurrentModificationException は、コレクション オブジェクトのトラバース中にコレクション オブジェクトを変更または削除することによって発生します。この問題が発生する理由:
- コレクションはトラバース時にロックを取得する必要があり、変更および削除操作も同じロックを取得する必要があります。このとき、デッドロック状況が発生します。結果として例外がスローされます。
- コレクションを走査するときに、他のスレッドが同時にコレクションを変更または削除すると、元のイテレータは無効になり、ConcurrentModificationException 例外がスローされます。
- コレクションのイテレータを使用して操作する場合、コレクションがイテレータ自身のremove()メソッドで変更されると、ConcurrentModificationExceptionもスローされる可能性があります。
2. 解決策
ConcurrentModificationException 例外は、スレッド セーフティの問題によって発生します。この問題を解決するには、対応する措置を講じる必要があります。解決策はいくつかあります:
- 同期ブロックと同期メソッドの使用
##同期ブロックまたは同期メソッドを使用して、スレッド セーフティの問題を解決できます。たとえば、synchronized キーワードを使用して反復プロセス中にコレクションをロックし、異なるスレッドが同時にコレクションを変更できないようにすることができます。この方法は、1 つのスレッドの操作が完了するまで待機してから次のスレッドの操作に進む必要があるため、比較的非効率的です。
CopyOnWrite コンテナの使用-
同期ブロックや同期メソッドと比較して、CopyOnWrite コンテナはより効率的です。 「コピーオンライト」メカニズムを使用して、操作を変更または削除するときにデータを保存する新しいコンテナを作成することで、同時変更の問題を回避します。 CopyOnWrite コンテナーは、キャッシュされたデータの保存など、読み取り操作の頻度が高く、書き込み操作の頻度が低いシナリオに適しています。
イテレータの削除メソッドを使用する-
イテレータを使用する場合は、コレクション自体を使用するのではなく、イテレータの削除メソッドを使用して要素を削除することをお勧めします。 Iterator の delete メソッドを使用すると、要素を削除するだけでなく、イテレータの現在位置に基づいて削除する要素を決定できるため、反復中に ConcurrentModificationException が発生しないようにできます。
並行コンテナの使用-
Java の並行コンテナは、ConcurrentHashMap、ConcurrentLinkedQueue など、スレッド セーフなコンテナ クラスを提供します。これらは、スレッド セーフを確保するだけでなく、同時実行性の確保 読み取りおよび書き込み時のパフォーマンスも非常に効率的です。並行コンテナを使用すると、ConcurrentModificationException 例外を回避できるだけでなく、プログラムのパフォーマンスも向上します。
概要:
ConcurrentModificationException 例外はスレッド セーフティの問題の 1 つであり、同期ブロック、同期メソッド、CopyOnWrite コンテナ、Iterator の削除メソッド、Concurrent コンテナの使用など、さまざまなソリューションで処理できます。等実際のアプリケーションでは、プログラムの安全性と効率性を確保するために、特定のビジネス ニーズに基づいて適切なソリューションを選択する必要があります。
以上がJava での ConcurrentModificationException 例外の原因と解決策の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。