JavaのコレクションはConcurrentModificationExceptionが後に有効な、利用可能な状態であることが保証されていますか?

Haldeanブラウン:

私が使ってGUIアプリケーションを書いています即時モードGUIパターンを、およびUIは、アプリケーションのパワーは実際の機能そのエンジンに別のスレッドで実行されます。概念的エンジンスレッドによって「所有」、およびこれらのリストは、極めてまれにしか変更されているオブジェクトの多くのリストを反復アップGUIスレッドが終了します。GUIスレッドは、それが約60Hzで動作を意味し、vsync'ed、およびエンジンのスレッドが200Hzの程度で動作します。

時々、UIのアクションがエンジンにコレクションの内容を変更します、と私は、これらの変異は中に何が起こっているかと衝突しないことを保証するために、これらの変異を行うためにエンジンのスレッドにランナブルを投稿するメッセージパッシングシステムを持っていますエンジン。そうすれば、私はエンジンが常に自分のアプリケーションのために非常に重要であり、データの一貫性のあるビューを見ていることを確認することができます。

エンジンは、すべてのデータの変異を担当しているので、しかし、時々 GUIがそれを反復している間エンジンは、コレクションの内容を変更することを発生し、これらのコレクションは、標準のJavaコレクションであるため、これは予想通り、正しくスローしますConcurrentModificationException私はこれに対処するには、いくつかのハイレベルな方法を考えることができます。

  1. ロック、いずれかの同期コレクションや読み書きロックを使って、
  2. GUIスレッドが読み込むデータをダブルバッファリング、およびGUIスレッドは、それがフレームの描画行うの時に2重バッファ・反転持っています
  3. CMEとアボートを無視し、「悪い」突然変異が起きたフレームのための部分的な情報を描画し、ちょうど次のフレームに進みますフレームの残りの部分を、描画

ロックは大幅なパフォーマンスのペナルティが付属しており、エンジンのスレッドからロックの獲得を待っている間、それは時々ストールにGUIの罰金だろうが、それはエンジンのスレッドが一貫した速度で実行するために非常に重要であり、さらにR / Wロックは、エンジンのスレッドで屋台を引き起こします。あるので、ダブルバッファリングは、かなりの複雑付属していますたくさんの各フレーム上のGUIによって読み取られたデータのは。

私は、そのオプション3は醜いです、そして私の質問は、ある意味では「権利の問題ではない」であることを知っているので、私はあなたにこのような背景のすべてを与えます。Javadoc ConcurrentModificationExceptionさえ氏は述べています:

フェイルファストの動作はそのまま、保証一般的に言えば、非同期の同時変更の存在下で任意のハード保証を行うことは不可能することはできません。フェイルファストオペレーションは最善努力原則に基づき、ConcurrentModificationExceptionを投げます。ConcurrentModificationExceptionがバグを検出するためにのみ使用する必要があります。したがって、正確を期すためにこの例外に依存するプログラムを書くことは間違っているだろう。

だが!私は、CMEによって損なわれることになる単一のフレームのためのGUIの正しさに関係しておりません。私は、唯一の次のフレームに何が起こるかと心配です。私の質問にどのリード線:それは(私はのための答えの中で最も興味のJavaコレクションを引き続き使用しても安全であるArrayListHashMapした後)ConcurrentModificationExceptionにそのイテレータからスローされましたか?それが可能だろうと論理的と思われるが、私はCMEがスローされた後にオブジェクトがまだ使用可能な状態になることを述べている文書の部分を見つけることができません。もちろんイテレータは、その時点でトーストですが、私は例外を飲み込むと、コレクションの使用を継続したいと思います。

ピーターLawrey:

ほとんどのコレクションのために、限り、あなたは唯一のライターを持っているとして、あなたはおそらく大丈夫ですが、保証はありません。あなたはHashMapの上に複数のライターを持っている場合、あなたはそれの構造で無限ループがあり、破損マップで終わることができます。

私はあなたが使用することをお勧めReentrantLock持っているtryLock()あなたは、ブロッキング最小限に抑えるためにit's--使用されていないだけで、取得・ロック-IF-アプローチをサポートする場合の方法を。

別のスレッドからのデータを供給するための別の方法はにあるQueueそう忙しくないエンジンを拾うことができます修正作業。これは、一つのスレッドだけですべてのアクセスを許可します。

ところで:ロック/ロック解除は、あなたがこのに多くを行う場合を除き、あなたに大きな違いを作ることはほとんどありません約1マイクロ秒を要します。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=137313&siteId=1