web-dev-qa-db-ja.com

SwingUtilities.invokeLaterは何をしますか?

SwingUtilities.invokeLater 行う? runメソッド内のコードブロックの実行を遅らせるだけですか? invokeLater関数内でアクションを呼び出すことと、実行したいスレッドの最後で単に呼び出すことの違いは何ですか? invokeLater関数が実際に何をするのか、誰でも私を助けることができますか?

37
user633784

他の答えが言ったように、AWTイベントディスパッチスレッドでRunnableを実行します。しかし、なぜそれをしたいのでしょうか? Swingデータ構造はスレッドセーフではないため、プログラマにそれらへの同時アクセスを簡単に達成できる方法を提供するために、Swingデザイナーは、それらにアクセスするすべてのコードが同じスレッドで実行する必要があるというルールを定めました。これはイベント処理とメンテナンスコードの表示のために自動的に行われますが、もちろん、新しいスレッドで長時間実行されるアクションを開始した場合、その進行状況または完了をどのように通知できますか? Swingコントロールを変更する必要があり、イベントディスパッチスレッドからそれを行う必要があります。したがって、invokeLater

27

AWTスレッドでコードを実行します。これにより、他のスレッドからGUIを変更できます。

Docs から:

DoRun.run()をAWTイベントディスパッチスレッドで非同期的に実行します。これは、保留中のすべてのAWTイベントが処理された後に発生します。このメソッドは、アプリケーションスレッドがGUIを更新する必要がある場合に使用する必要があります。

9
MByD

既に説明したように、InvokeLaterを使用すると、EventQueueで実行していないときに、swingクラスのメソッドを安全に呼び出すことができます。ただし、EventQueueから他のフィールドとクラスonlyにアクセスすることで、コードと生活を簡素化できます。マルチスレッドの手間をかけずに、スイングやお互いに対応できます。別のスレッドを開始した場合は、InvokeLaterを使用して、できるだけ早くEventQueueに戻り、同期する必要があるフィールドまたは保護するフィールドの数を最小限にします。

複数のコアを最大限に活用する必要がある場合は、EventQueueの使用を削減する必要があり、複雑さに大きな代償を払わなければなりません。

2
RalphChapin

それはコメントになりますが、...と同じくらい長いように見えます、ただ基本的なもの

1/GUIを正しく更新するために独自のEDTを作成します。単純なVanillaを使用してコードを実行する場合 ThreadJava.util.TimerExecutor .. more here =

2/set Focus to JComponents iof some some Listeners if if there is f.e. DocumentListenerFocusを目的のJComponentsに設定するのは難しい

3 /遅延コード実行はブロックし、それをEDTの最後に移動します

2
mKorbel

最終的に、every invokeLater(doRun)を呼び出す時間でdoRun.run()メソッドの呼び出しを取得することに注意してください。そのため、イベントスレッドがその処理を実行する機会を得る前に10回呼び出すと、doRun.run()の呼び出しが10回連続して行われる可能性があります。

1
gerardw