私は取得していますjava.util.ConcurrentModificationException
が、どのクラスがこの例外を与えているかを理解する必要があります。コードには多数のクラスとパッケージが含まれており、エラーが発生した場所を特定するのは困難です。例外は、の問題を示していますArrayList
。疑わしい領域で例外処理を使用すると、例外がキャッチされません。
方法はありますか?
私は取得していますjava.util.ConcurrentModificationException
が、どのクラスがこの例外を与えているかを理解する必要があります。コードには多数のクラスとパッケージが含まれており、エラーが発生した場所を特定するのは困難です。例外は、の問題を示していますArrayList
。疑わしい領域で例外処理を使用すると、例外がキャッチされません。
方法はありますか?
最新のIDE、たとえばEclipseを使用している場合は、アプリケーションをデバッグモードで実行し、任意の例外にブレークポイントを設定できます。効果:例外が(JVM全体で)スローされるたびにアプリケーションが停止し、スタックトレースを取得します。
これにより、呼び出し元(および同時実行の問題の場合は実際のスレッド)を簡単に識別できます。
playn.java.JavaGroupLayer.paint(JavaGroupLayer.java:96)
それは悪者です。それはあなたのクラスのpaint
メソッドです。JavaGroupLayer
おそらく、配列リストを反復処理するforループがあり、ある時点で、リストが変更されたことを検出します。
スイングアプリケーションでスレッドを使用していますか?その場合は、レイアウトが変更されていないことを再確認してください。
通常、スタックトレースの最上位から開始し、作成/認識した最初のクラスをエントリポイントにする必要があります。その後、おそらく他のクラス/メソッドで呼び出しを行うので、スタックトレース、つまり問題のあるコードをたどることができます。
さらに:おそらくあなたがしていること(私は過去にそれを自分でやったことがあります)は、コレクションを繰り返しながら、コレクションを変更しようとしています。これが同時変更の意味です。あなたがそれをどこでやっているのか見てみてください。
スタックトレースを上から下に見ていきます。ソースコードに属する最初のクラスは、ArrayList
それを使って違法なことをしようとしたことから例外を受け取ったクラスです。ArrayList
次に、どのスレッドが同時にそのインスタンスにアクセスしているかを確認し、synchronized
メソッドまたはsynchronized
ブロックで保護します。
よくある間違いは、例外を破棄し、メッセージを読み取るか、例外をtoStringすることだけです。スタックトレースを印刷すると、スタックの各レベルのどこ(クラス、メソッド、および行)を正確に確認できます。
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:782)
at java.util.ArrayList$Itr.next(ArrayList.java:754)
at playn.java.JavaGroupLayer.paint(JavaGroupLayer.java:96)
at playn.java.JavaPlatform$1.paint(JavaPlatform.java:222)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5138)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1454)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1385)
IDEでは、各行をクリックして、関連するコードを確認できるはずです。
これがパッケージに含まれていることを考えると、問題はライブラリを誤って使用したことである可能性が高くなります。plynはマルチスレッドセーフではないようで、スワップAWTスレッドを使用する代わりに別のスレッドのデータ構造を変更しようとしました。
リストを特定し、イテレータ反復 (x:list の場合) ではなくリスト反復 (i=0; i < list.size(); i++ の場合) を使用するように反復を変更します。
または、リストの浅いコピーを作成して、それを繰り返すこともできます。