1

スプライトのリストのリストを使用してすべてのスプライトを保持するゲームエンジンを作成しようとしています(リストのリストを使用すると、スプライトを適切な方法で並べ替えることができます)。問題は、スプライトを繰り返し追加および削除する必要があることです。これは、フェイルファストイテレーターに非常に迅速に違反し、同時変更の例外が発生します。リストに複数のイテレータを含めることはできますか?これにより、例外が停止しますか?これに失敗した場合、リストのイテレータを「解放」して、リストが変更をチェックしないようにする方法はありますか?

4

2 に答える 2

2

反復の進行中に発生する変更に関係なく、特定の時間に存在するリストの内容を反復したい場合は、単にコピーを作成して、そのコピーを反復する必要があります。

これはパフォーマンスの観点からは恐ろしいことのように聞こえるかもしれませんが、試してみてCopyOnWriteArrayList、プロファイリングによってコピーの作成が完成したアプリケーションのホットスポットであることが実際に示されている場合にのみ、代替案(など)を検討することをお勧めします。ガベージコレクターは、これらのコピーのような短命のオブジェクトを非常にうまく機能させるのに非常に優れています。

于 2012-08-30T02:19:50.690 に答える
1

リストに複数のイテレータを含めることはできますか?これにより、例外が停止しますか?

はい、できますが、できません。(イテレーターはリストの状態をチェックして、同時変更が発生したかどうかを判別します。)

これに失敗した場合、リストのイテレータを「解放」して、リストが変更をチェックしないようにする方法はありますか?

いいえ、少なくとも標準のリストクラスにはありません。また、フェイルファストイテレータが回避するように設計されている種類の異常やデータの破損につながる可能性があるため、これは悪い考えです。(アプリケーションがConcurrentModificationExceptionで予想どおりに失敗するか、ランダムなデータ構造の破損や奇妙な例外でときどき失敗するかを選択しますか?)

イテレータが同時変更を許可する代替のList実装クラスを検討する必要があると思います。アプリケーションがリストをどのように使用しているかに応じて、次のような可能性があります。

  • CopyOnWriteArrayListこれには完全なリストセマンティクスがありますが、書き込み操作は少しコストがかかる傾向があります。

  • ConcurrentLinkedDequeこれは、リストに期待するほとんどの操作(ただし、位置の挿入または削除は除く)であり、書き込み操作の方が安価です。

どちらの場合も、イテレータは、反復ですべての要素が表示されるかどうかについて、より弱い保証を提供します。セマンティクスが適切であることを確認するために、それぞれのjavadocを注意深く読む必要があります。

いくつかの歴史的な例外を除いて、のコレクションタイプはjava.util同時/マルチスレッドのユースケース向けに設計されていません。アプリケーションで複数のスレッドからアクセスされるコレクションタイプが必要な場合は、java.util.concurrentパッケージ内の実装を確認する必要があります。

于 2012-08-30T01:57:42.040 に答える