2

を使用してJFrameを開始する非GUIスレッドがあります

java.awt.EventQueue.invokeLater(new Runnable() {

    public void run() {
        cardReadPunchGUI = new IBM1622GUI();  // instantiate
        cardReadPunchGUI.setVisible(true);
    }
});

IBM1622GUIのコンストラクターの一部は、それ自体の「モデル」をインスタンス化します。これには、非GUIスレッドがアクセスする必要があります。

cardReadPunch = IBM1622GUI.getModel();

非GUIスレッドが「後で呼び出された」新しいGUIと同期する正しい方法は何ですか?(もちろん、同期がないと、IBM1622GUI.getModel()nullが返される傾向があります。)

4

4 に答える 4

4

使用する

javax.swing.SwingUtilities.invokeAndWait(Runnable doRun);

代わりは。

doRun.run()がAWTイベントディスパッチスレッドで同期的に実行されるようにします。この呼び出しは、保留中のすべてのAWTイベントが処理され、(その後)doRun.run()が返されるまでブロックされます。

于 2011-08-03T03:10:52.710 に答える
2

1に初期化されたCountDownLatchを非GUIスレッドとGUIスレッドの両方と共有することをお勧めします。

起動時に非GUIスレッドが呼び出さlatch.await()れ、ブロックされた状態になります。

GUIスレッドはlatch.countDown()、初期化が完了すると呼び出しを行います。その後、非GUIスレッドはawait呼び出しを終了し、両方のスレッドが同期されます。

于 2011-08-03T03:12:26.357 に答える
2

ええと、あなたがそれにアクセスできるなら、あなたはいつでもその特定のロジックをSwingスレッドの外に、そしてを呼び出すスレッドに移動することができますinvokeLater。のコンストラクターが適切に動作していると仮定すると、Swingスレッドからそこで実行していることを実行することについて危険なことは何もありませんIBM622GUI

それ以外にも、さまざまなメカニズムを利用できます。

  1. invokeAndWaitcgullが私を殴って言ったように、あなたは使うことができます。
  2. ランナブルに直接参照の代わりにの値を設定させ、futureのメソッドFutureを呼び出すことでメインスレッドをブロックすることができます。get
  3. メインスレッドとSwingスレッドCountDownLatchの開始カウントが1である可能性があります。await()countDown()

同期を支援するユーティリティはたくさんあります。

于 2011-08-03T03:12:50.380 に答える
1

通常、パラメータをスレッドに渡します。バックグラウンドでロジックを実行します。次に、SwingUtilities.invokeLater()を使用して、これらのオブジェクトのいずれか、またはUIスレッドのUI要素に対して行う必要のある変更をポストバックします。通常、バックグラウンドスレッドで実行するものと、UIスレッドで実行するものを指定できる単純なユーティリティを作成します。SwingWorkerは、使用するのが非常に苦痛だと思いますが、使用できるものです。このような単純なもの:

new AsyncThread<Param,T>() {
   public T executeInBackground( Param param ) {
      // do something long running
      T result = // do something long running;
      return T;
   }

   public void executeOnUI( T result ) {
      // update the UI here, or modify the model, etc.
   }
}.execute( param );

AsyncThreadは、別のスレッドでexecuteInBackground()メソッドを実行します。次に、内部的にSwingUtilities.invokeLater()を使用してUIスレッドにポストバックします。次に、executeOnUIはUIスレッドで実行されます。execute()メソッドは、バックグラウンドで実行したり、例外を処理したりするためのスレッドを作成できます。

GUIにスレッドを開始させ、GUIにそのモデルまたは必要な部分をスレッドに渡させます。逆の代わりに。そうすれば、実行中のバックグラウンドスレッドに関するフィードバックをUIに提供させることができます。ただし、UIスレッドが同時に読み取り/書き込みを行うモデルのメンバーにバックグラウンドスレッドをタッチ(書き込み/変更/変更)させることはできません。したがって、バックグラウンドスレッドに応じてモデルを変更する予定がある場合は、安全のためにモデルをUIスレッドにポストバックしてください。

于 2011-08-03T03:11:45.190 に答える