6

私が読むことができるのは、スイングアプリで新しいスレッドをディスパッチして「バックグラウンド」作業を実行するために使用されますが、「通常の」スレッドではなくこれを使用する利点は何ですか?

新しいスレッドを使用して、SwingUtilities.invokeLater を使用していくつかの GUI メソッドを呼び出すのは同じではありませんか?...

ここで何が欠けていますか?

http://en.wikipedia.org/wiki/SwingWorker

http://java.sun.com/products/jfc/tsc/articles/threads/threads2.html

4

7 に答える 7

10

はい、SwingWorker がバニラ スレッド + invokeLater で行うことを実行できます。SwingWorker は、バックグラウンド スレッドでタスクを実行し、EDT で結果をレポートする、予測可能な統合された方法を提供します。SwingWorker はさらに、中間結果のサポートを追加します。繰り返しますが、これはすべて自分で行うことができますが、特に同時実行に関しては、統合された予測可能なソリューションを使用するのが簡単な場合があります。

于 2008-11-11T19:39:15.037 に答える
3

コード例:

import org.jdesktop.swingx.util.SwingWorker; // This one is from swingx
                                             // another one is built in 
                                             // since JDK 1.6 AFAIK?

public class SwingWorkerTest {

  public static void main( String[] args ) {

    /**
      * First method
      */
    new Thread() {

      public void run() {

        /** Do work that would freeze GUI here */

        final Object result = new Object();
        java.awt.EventQueue.invokeLater( new Runnable() {

          public void run() {
          /** Update GUI here */
          }
        } );

      }
    }.start();

    /**
      * Second method
      */
    new SwingWorker< Object , Object >() {

      protected Object doInBackground() throws Exception {
        /** Do work that would freeze GUI here */

        return null;
      }

      protected void done() {
        try {
          Object result = get();
          /** Update GUI here */
        }
        catch ( Exception ex ) {
          ex.printStackTrace();
          if ( ex instanceof java.lang.InterruptedException )
            return;
        }
      }
    }.execute();
  }

}

選択は常に個人の好みとユースケースに依存します。

2番目の方法は、リファクタリング時に利点があります。使用されているメソッドが大きすぎる場合は、匿名クラスをより簡単に内部クラスに変換できます。

私の個人的な好みは2番目です。SwingWorkersを追加して次々に実行できるフレームワークを構築したからです...

于 2008-11-12T07:09:41.913 に答える
2

SwingWorkerは、一般的なパターンの実装です(.Netには、このためのGuiWorker BackgroundWorkerがあります)。ここでは、GUIプログラムでいくつかの作業を行う必要がありますが、GUIの応答性は維持されます。問題は、多くの場合GUIライブラリがマルチスレッドセーフではないことです。そのため、このようなワーカーを実装する一般的な方法は、ライブラリのメッセージループを使用して、アプリケーションのイベントループにメッセージを転送することです。

これらのクラスを使用すると、GUIを簡単に更新できます。通常、update(int status)スレッドが作業を継続している間、スレッドによって呼び出され、クラスによってディスパッチされ、GUIによって処理されるメソッドがあります。

通常のスレッドを使用すると、このタスクのために独自のイベントまたはその他のメッセージングメカニズムをコーディングする必要があります。これは、この機能が頻繁に必要になる場合に問題になる可能性があります。たとえば、JavaでinvokeLaterを使用すると、GUIを更新するためのコードを作業を行うためのコードに混在させることができます。SwingWorkerを使用すると、物事を分離しておくことができます。

于 2008-11-11T19:19:01.847 に答える
1

あなたの質問に答えるために、あなたは何も見逃していません。このクラスは、説明した機能をまとめるための便利なユーティリティです (別のスレッドを開始してバックグラウンド作業を実行し、結果を使用して EDT で最終アクションを呼び出します)。

于 2008-11-11T19:36:32.187 に答える
1

Swing を使用する場合、swing のメイン処理 (つまり、レンダリング) が単一のスレッド (メイン スレッドではない) で行われることを知っておくことが重要です。これは、多くの場合、Swing または awt イベント スレッドと呼ばれます。1.6 より前の JDK に精通している人は、swing コンポーネントのイベント ディスパッチャに長時間費やした場合の「灰色の四角形」バグを覚えているでしょう。これは何を意味するのでしょうか。どのスイングアプリケーションでも、2 つのスレッドが実行されており、これに対処する必要があります。通常、イベント ディスパッチャー内のすべての操作 (ボタンがクリックされたときに実行されるコード) が短い場合 (つまり、ボタンの状態を変更する) は、イベント ディスパッチャー内でこれを実行できます。アプリケーションが Web サービスまたはデータベースを呼び出す場合、またはアプリケーションの状態が外部イベント (つまり. jms) または単に UI をよりインタラクティブにしたい (つまり、アイテムのリストを作成し、他のことを実行できるようにする) 場合は、awt イベント スレッド (メインのスイング スレッド) 以外のスレッドを使用する必要があります。したがって、これらの場合、新しいスレッドを生成して必要な処理を行い、最終的に結果が戻ってきたら、awt/swing ディスパッチャーによって実行できるイベントを何らかの方法で作成する必要があります。SwingWorker は、これを可能にする小さな設計パターンです (もう 1 つの方法は SwingUtilities です)。これは、外部ソースからデータをフェッチしたり、長い計算 (グラフィック シーンのレンダリング) を行う場合に特に便利です。外部スレッド (awt スレッド以外) からの結果のディスパッチとその後の再統合を自動化するのに役立ちます。非同期イベントの場合 (つまり、JMS からのイベントで結果を更新する必要がある場合は、SwingUtilities を使用します)。

于 2009-06-03T15:30:41.043 に答える
0

SwingWorker単純なサンプル コードをより簡潔にします。ただし、泥のボールを作成します。GUI と実行されたロジックとの間の通信はすべて結合されています。したがって、実際の製品コードで使用されるのは見たくありません。

于 2008-11-12T14:38:43.973 に答える
0

SwingWorker は、独自のスレッドをいじるよりもはるかに簡単です。なぜなら、UI とバックグラウンド プロセスの間のスレッド調整と効果的なループの実行、作業を続けて UI に段階的に更新を送り返すバックグラウンド作業という、手動では面倒な 2 つのことを提供してくれるからです。大量のデータを処理したり、大きなリストをロードしたりします。欠点 (または利点) は、見方によって異なります。つまり、基になる実装が隠されているため、将来のバージョンでは動作やパフォーマンスなどが異なる可能性があり、望ましくない可能性があります。UI イベントと独自のコマンド コードとの間の接着剤として、SwingWorker が UI へのリンクを維持し、コードがデータをポンプするので、非常に便利であることがわかりました。

于 2008-11-16T00:53:28.903 に答える