2

呼び出したときにランダムに例外が発生することに気付いたとき、私は最終的なゲームを作成している最中でしたrepaint();

Threadすべての原因は、さまざまなオブジェクトがさまざまなタイミングで更新され、それ自体を更新する独自のものを持っていたことです。時折、描画中にエンティティが更新されることがあります。ペイント スレッドは約 60 ~ 100 FPS で実行されますが、エンティティは約 300 ミリ秒ごとに更新されます。

これに関連して、ゲームが停止したり、その他の問題が発生したりすることはありません。

無視するのは悪い考えだとはわかっていますが、他にできることはありますか?ゲームを機能させるために考えられる唯一の解決策は、複数のスレッドを用意することです。

読んでくれてありがとう!

編集: ペイント中にエンティティを削除しようとすると、問題が発生するようです。どちらも同じリストを使用します。

4

2 に答える 2

6

ConcurrentModificationExceptionは、マルチスレッドとは何の関係もありません(ただし、複数のスレッドが関与する可能性があります)。Listこれは、メソッド以外の方法でアイテムがコレクションに追加またはコレクションから削除されているときに、コレクション(たとえば、)を反復処理しているときに発生しますIterator.remove()

これは別のスレッドで発生する可能性がありますが、同じスレッドである可能性があります。たとえば、このコードはConcurrentModificationExceptionもスローします。

Iterator iter = someList.iterator();
while(iter.hasNext()) {
   Object item = iter.next();
   someList.remove(item);
}

代わりiter.remove()に呼び出された場合、エラーは発生しなかったでしょう。

これを回避する方法:

  1. リストを繰り返す前に、リストのコピーを作成してください
  2. remove()イテレータのメソッドのみを使用してください
  3. CopyOnWriteArrayList変更のたびに内部配列のコピーを作成することを犠牲にして、このエラーを回避するようなものを使用してください。
于 2012-05-26T16:14:19.193 に答える
1

マルチスレッドの主な問題は、オブジェクトの状態が複数のスレッド間で共有されているにもかかわらず、この状態が常に一貫していることを正確に確認することです。これが、同期ブロックが存在する理由、ロックが存在する理由、揮発性変数が存在する理由です。

この問題を無視して、深刻な問題が発生しないことを願うだけでは、惨事につながります。すべてが 1 時間正常に実行され、その後、どこでも例外が発生したり、誤った結果が得られたりします。

2 つのスレッドが同じ非スレッド セーフ リストに同時にアクセスできるという事実は、コードにバグがあることを示しています。それは明らかに間違っており、間違いなく修正する必要があります。

共有リストへのアクセスを同期する必要があります。複数のスレッドが実行されている場合、同期はオプションではないため、Java の並行性に関するチュートリアルや本を読んでください。

于 2012-05-26T16:33:31.737 に答える