次のシナリオを考えてみましょう。複数の SwingWorker が同時に実行され、さまざまなタスクを表しています。要件は、すべてのタスクが完了したら、タスクの進行状況を表す関連ラベルをすべてアプリケーション ウィンドウから削除することです。
課題は、すべての SwingWorker が実行を終了した後にのみラベルの削除が実行されるようにすることです。 。これは、UI での不必要なちらつきや一貫性のない動作を防ぐために不可欠です。
この問題に対処する適切なアプローチは、CountDownLatch を使用することです。この構造は、指定された数のイベントが発生するまで 1 つのスレッドを待機できる同期メカニズムを提供します。この特定のコンテキストでは、CountDownLatch は SwingWorkers の数に等しいカウントで初期化されます。各ワーカー スレッドは、完了時にラッチ カウントをデクリメントする責任があります。
「スーパーバイザー」として機能する別個の SwingWorker がラッチを監視するために使用されます。このスーパーバイザ ワーカーは CountDownLatch.await() メソッドをブロックし、他のすべての SwingWorker が完了の信号を送信するまで事実上一時停止します。ラッチ カウントが 0 に達すると、スーパーバイザー ワーカーはアプリケーション ウィンドウからすべてのラベルを削除します。
次のコード スニペットは、このソリューションの実装を示しています。
import java.util.concurrent.CountDownLatch; ... private class Supervisor extends SwingWorker<Void, Void> { CountDownLatch latch; public Supervisor(CountDownLatch latch) { this.latch = latch; } @Override protected Void doInBackground() throws Exception { latch.await(); return null; } @Override protected void done() { for (JLabel label : labels) { label.setText("Fin!"); label.setBackground(Color.lightGray); } startButton.setEnabled(true); //panel.removeAll(); panel.revalidate(); panel.repaint(); } } ... private static class Counter extends SwingWorker<Void, Integer> { private JLabel label; CountDownLatch latch; public Counter(JLabel label, CountDownLatch latch) { this.label = label; this.latch = latch; } @Override protected Void doInBackground() throws Exception { int latency = rand.nextInt(42) + 10; for (int i = 1; i <= 100; i++) { publish(i); Thread.sleep(latency); } return null; } @Override protected void process(List<Integer> values) { label.setText(values.get(values.size() - 1).toString()); } @Override protected void done() { label.setBackground(Color.green); latch.countDown(); } }
この実装では、CountDownLatch がゲートキーパーとして効果的に機能し、すべての SwingWorker がラベルの削除を完了した後にのみラベルの削除が実行されるようにします。タスク。このアプローチは、非同期操作中の不要な視覚的アーティファクトを回避することで、クリーンで一貫性のあるユーザー インターフェイスを促進します。
以上がCountDownLatch は、複数の SwingWorkers が終了したときに UI の一貫性をどのように確保できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。