こんにちは私はSwingWorkerを使ってスイングアプリのGUIを更新する方法を学びました。2人の同時スイングワーカーのdone()メソッドが正しい順序でEDTで実行されるようにするにはどうすればよいですか?
私は2つのスイングワーカーが同時に実行できる(それぞれが別のボタンから起動される)場合、EDTで完了メソッドが呼び出されていることを確認する方法(GUIを更新する)彼らは解雇されましたか?
私の所見とアイデア: 私はdoInBackground()メソッドをロックに同期させて、処理を続行する前にもう一方のタスクを完了するまで待たなければならないことを確認しました。問題は、(2番目のワーカーが同期ブロックで待機している間に)swingworker_1がdoInBackground()を終了するのを見ることができましたが(2番目のワーカーが同期ブロックで待機しています)、swingworker_2のdoneメソッドはEDT swingworker_2の後に終了しても、swingworker_1のdoneメソッドの前に。私はdoInBackground()が返る直前にpublishを使用することを考えましたが、これはいつもうまくいくようですが、最終的な結果ではなく中間結果に使用されるように思われるので、悪い習慣かもしれません。もう1つの可能性は、返す前にguiを更新するためにdoInBackground()内でSwingUtilities.invokeLaterを使用することですが、やはり悪い習慣であるかもしれません。前もって感謝します。
最初のボタンを押す私が使用し、テストした後、すぐに第二1:
//Code that runs in the first button
SwingWorker<Void, Void> swingworker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
synchronized (lock) {
System.out.println("Thread 1");
Thread.sleep(1000);
return null;
}
}
@Override
protected void done() {
System.out.println("Done with thread 1 ");
//update GUI
}
};
swingworker.execute();
//Code that runs in the second button
SwingWorker<Void, Void> swingworker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
synchronized (lock) {
System.out.println("Thread 2");
return null;
}
}
@Override
protected void done() {
System.out.println("Done with thread 2 ");
//update GUI
}
};
swingworker.execute();
UPDATE:ちょうど私が(swingworker_1またはswingworker_2)最初に起動する人にかかわっていないです明確にするだけによって異なりボタンが最初に押されるはずです。私が保証したいのは、ボタンからのワーカーが最初に実行された場合(つまり、ワーカーがdoInBackground()メソッドで同期化されて終了する場合)、EDTのguiを更新するためにエンキューする必要がある。私が見いだしたことは、たとえ作業者が同期していても、後で作業を開始する作業者が後で最初の作業の前にGUIを更新することがあっても、必ずしもそうなるとは限りません。
を私は疑問に思います?これらの労働者は何をしており、あなたのプログラムは何をしていますか? –
私自身、 'done()'メソッドの使用を避け、通常はPropertyChangeListenersを使ってワーカーの状態変更を待ち受けます。これにより、SwingWorkerはGUI固有の呼び出しを行う必要がなくなり、またGUIや呼び出しコードについての知識を持つことができます。 –
あなたのコードでは、第1のワーカーが第2のものより前に 'ロック 'のモニタを取得することを保証する何も表示されません。 –