何をしSwingUtilities.invokeLater
ますか?run
メソッド内のコードブロックの実行を遅らせているだけですか? invokeLater
関数内でアクションを呼び出すことと、実行したいスレッドの最後で単にアクションを呼び出すことの違いは何ですか? 関数が実際に何をするのか、誰かが私を助けることができますinvokeLater
か?
5 に答える
他の回答が言っているように、それはRunnable
AWTイベントディスパッチスレッドであなたを実行します。しかし、なぜあなたはそれをしたいのですか?Swingデータ構造はスレッドセーフではないため、プログラマーがそれらへの同時アクセスを防ぐための簡単な方法を提供するために、Swing設計者は、それらにアクセスするすべてのコードを同じスレッドで実行する必要があるというルールを定めました。これは、イベント処理と表示メンテナンスコードに対して自動的に行われますが、長時間実行されるアクションを開始した場合(もちろん、新しいスレッドで)、その進行状況または完了をどのように通知できますか?Swingコントロールを変更する必要があり、イベントディスパッチスレッドから変更する必要があります。したがってinvokeLater
。
AWT スレッドでコードを実行します。これにより、他のスレッドから GUI を変更できます。
ドキュメントから:
AWT イベント ディスパッチ スレッドで doRun.run() が非同期的に実行されるようにします。これは、保留中のすべての AWT イベントが処理された後に発生します。このメソッドは、アプリケーション スレッドが GUI を更新する必要がある場合に使用する必要があります。
すでに述べたように、InvokeLaterを使用すると、最初からEventQueueで実行していないときに、swingクラスのメソッドを安全に呼び出すことができます。ただし、 EventQueueからのみ他のフィールドやクラスにアクセスすることで、コードと作業を簡素化できます。それらは、マルチスレッドの煩わしさなしに、スイングや相互に機能します。別のスレッドを開始した場合は、InvokeLaterを使用して、できるだけ早くEventQueueに戻り、同期または保護する必要のあるフィールドの数を最小限に抑えます。
複数のコアを最大限に活用する必要がある場合は、EventQueueの使用を減らす必要があり、複雑さの点で大きな代償を払う必要があります。
それはコメントになりますが、同じくらい長く見えます...、基本的なものだけです
1 / GUIを正しく更新するために独自のEDTを作成します。プレーンなバニラスレッド、java.util.Timer、Executorを使用してコードを実行した場合は、fe 。詳細はこちら
2 / FocusをJComponentsに設定するのに役立ちます。いくつかのリスナーがあります。DocumentListenerがある場合はFocus
、目的のリスナーに設定するのが難しいためです。JComponents
3 /遅延コード実行はブロックし、それをEDTの最後に移動します
最終的には、invokeLater(doRun) を呼び出すたびに doRun.run( ) メソッドが呼び出されることに注意してください。したがって、イベント スレッドが処理を実行する機会を得る前に 10 回呼び出した場合、doRun.run( ) への呼び出しが 10 回連続して行われる可能性があります。