1

Java Set を同時に変更すると、ConcurrentModificationException が発生します。問題は、スタック トレースが、特定の Map イテレータで変更が発生したことを示していることです。マップはJavaでセットを実装するために使用されることを理解しましたが、これらの詳細は実装の内部にあります。内部 Map iterator Exception は、返されるべき Set Iterator 関連の例外内に適切にラップされている必要があると思います。

私は理にかなっていますか、それとも何かが欠けていますか? コード内に存在しない不完全な Map 操作を見つけようとして 2 日間を費やしたところ、問題の原因となっている Set 操作を最終的に見つけました (論理的なプロセスやドキュメントではなく、試行錯誤を通じてズームインしました)。どうすればこのようなフラストレーションを避けることができるのだろうか。

-----------UPDATE-------------- 私の質問は、同時実行を正しく行う方法に関するものではありません。私の質問は、このような役に立たないスタック トレース メッセージに惑わされないようにする方法です。Map Iterator 例外は、実際の SetIterator 例外の代わりにスタック トレースに表示されるビジネスはありません。これは、ユーザーの観点から意味があります。

4

3 に答える 3

1

表面的には少し奇妙に見えるかもしれませんが、そのようなエラーが発生した場合、スタックトレースは必要な情報を提供するはずです-トレースの最初の数行を無視してjava.util、あなたのいずれかへの最初の参照を探してください独自のクラス。この行は、デバッグ時に検索を開始する場所になります。

上のイテレータがHashSetセット関連の型ではなくマップ関連のように見える理由については、これは次の理由によるものです-の実装はHashSet.iterator単にを返しますbackingMap.keySet().iterator()。そのような「SetIterator」はありません。

于 2013-02-25T08:57:10.680 に答える
0

同時変更を可能にするセットを使用できます。ConcurrentSkipListSetやCopyOnWriteArraySetのように、代わりにGoogleGuavaには並行セットを取得するための追加の方法があります。

于 2013-02-25T08:20:27.420 に答える
0

ConcurrentModificationException は、コレクションが反復処理されているときに発生し、別のスレッドがそれを変更しようとします。またはその逆。私はあなたの主張を理解していますが、これを回避する簡単な方法は、コレクションが反復されていることを示すブール値のフラグを持つことです。そうすれば、変更スレッドは単にそのフラグが false になるのを待つことができ、スレッドがそのような衝突を起こすことはありません :)

于 2013-02-25T07:54:17.347 に答える