2012-03-20 9 views
2

Swingアプリケーションでデッドロックが発生していますが、回避策がありますが、私が何をしているのか理解できていない後で再びポップアップする可能性のある競合状態を隠しただけです。Swingアプリケーションのスレッディングとデッドロック

スレッドトレースは、AWT-EventQueue-0とAWT-EventQueue-1という2つのスレッド間でデッドロックが発生していることを示しています。私の最初の質問は、これらのいずれかが悪名高いイベントディスパッチスレッドである場合です。どちらのスレッドがそのスタックトレースの下部に次き:

at java.awt.EventDispatchThread.run(EventDispatchThread.java:138) 

私は、問題の根本は、グラフィカルなコンポーネントとアプリケーションのクラスミックスドメインデータは、この場合には、両方のスレッドが両方をロックしようとしているということだと思いますa java.awt.Component$AWTTreeLockと自分自身のオブジェクトの1つ(Xと言う)。私の回避策は、既にEDTにあるにもかかわらず、Xがロックされている1か所でSwingUtilities.invokeLater()を使用することです。 Javadocによると、これは、 "保留中のすべてのイベントが処理されるまで延期"という呼び出しを意味します。しかし、私はこれが本当に解決策であるとは確信していません。いずれにしても2つのEDTがあるように思われる理由は不明です。

誰でも何が起こっているのか説明できますか?私はコードのカットダウン版を提供しようとすることができますが、無関係な合併症を編集するにはしばらく時間がかかるかもしれません。

+2

このプロセスでモーダルダイアログを開きますか?または、あなたのコードは新しいQueueをプッシュしますか? – Yishai

+0

ああ、そうです!私はその仕組みを見なければならないでしょう。既存のキューを置き換えませんか?なぜ2つのAWT-EventQueueスレッドが発生するのでしょうか? – Ben

答えて

1

正しい方向に私を向けるYishaiに感謝します。アプリケーションは、独自のサブクラスjava.awt.EventQueueをインスタンス化し、Toolkit.getDefaultToolkit().getSystemEventQueue().push(newQueue)を使用して元のキューを置き換えます。元のキューは、スレッドAWT-EventQueue-1の新しいキューにイベントが到着すると同時に、スレッドのタスクを処理中である必要があります(AWT-EventQueue-0)。デッドロックが発生します。

0

どこにスレッドを作成していますか?そうならば、

http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html

または

スイングでうまく動作代わり

http://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html

を使用することを検討してください。

+0

いいえ、明示的に新しいスレッドを作成していません。ちょうどいくつかの初期化メインスレッド(そのうちのいくつかはinvokeLaterを使用してEDTに移動しました)とSwingコンポーネントのイベントハンドラはEDTで呼び出されます。とにかくそうなっているのです。 – Ben

関連する問題