ホームページ > Java > &#&チュートリアル > 複数の同時実行 SwingWorkers の完了を調整するにはどうすればよいですか?

複数の同時実行 SwingWorkers の完了を調整するにはどうすればよいですか?

Susan Sarandon
リリース: 2025-01-01 11:28:10
オリジナル
637 人が閲覧しました

How to Coordinate the Completion of Multiple Concurrent SwingWorkers?

複数の SwingWorkers を待機しています

SwingWorker は、バックグラウンド タスクを実行し、ワーカー スレッドから GUI を更新する便利な方法です。ただし、複数の SwingWorker インスタンスが同時に実行され、それらの完了を調整する必要がある場合があります。

複数の SwingWorker がループ内で作成および実行される次のコードを考えてみましょう。

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import javax.swing.*;

public class TestApplet extends JApplet {

    @Override
    public void init() {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    createGUI();
                }
            });
        } catch (InterruptedException | InvocationTargetException ex) {
        }
    }

    private void createGUI() {
        getContentPane().setLayout(new FlowLayout());
        JButton startButton = new JButton("Do work");
        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                for (int i = 0; i < 10; i++) {
                    new SwingWorker<Void, Void>() {
                        @Override
                        protected Void doInBackground() throws Exception {
                            // Do some work
                            return null;
                        }
                    }.execute();
                }
            }
        });
        getContentPane().add(startButton);
    }
}
ログイン後にコピー

「作業を実行」ボタンをクリックすると、10 個の SwingWorker インスタンスが作成され、実行されます。各 SwingWorker はバックグラウンドでいくつかの作業を実行し、作業が完了すると GUI を更新します。ただし、SwingWorkers 間には調整がありません。つまり、SwingWorkers は任意の順序で完了する可能性があり、特に基になるタスクにかかる時間が異なる場合、GUI が不規則に更新される可能性があります。

GUI を確実に更新するには一貫性のある予測可能な方法で、SwingWorkers の完了を調整することが重要です。これを実現するにはいくつかのアプローチが使用できますが、最も適切なアプローチはアプリケーションの特定の要件によって異なります。

1.バリア

バリアは、複数のスレッドがすべてのスレッドが共通点に到達するまで待機できるようにする同期メカニズムです。 SwingWorkers のコンテキストでは、バリアを使用して、次のようにすることで、すべての SwingWorker がタスクを完了した後にのみ GUI が更新されるようにすることができます。

import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.*;
import javax.swing.*;

public class TestApplet extends JApplet {

    private static final int NUM_WORKERS = 10;
    private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(NUM_WORKERS);
    private static final CyclicBarrier BARRIER = new CyclicBarrier(NUM_WORKERS, new Runnable() {

        @Override
        public void run() {
            // All SwingWorkers have completed, update the GUI
        }
    });

    @Override
    public void init() {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    createGUI();
                }
            });
        } catch (InterruptedException | InvocationTargetException ex) {
        }
    }

    private void createGUI() {
        JButton startButton = new JButton("Do work");
        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                for (int i = 0; i < NUM_WORKERS; i++) {
                    EXECUTOR.submit(new SwingWorker<Void, Void>() {

                        @Override
                        protected Void doInBackground() throws Exception {
                            // Do some work
                            return null;
                        }

                        @Override
                        protected void done() {
                            BARRIER.await();
                        }
                    });
                }
            }
        });
        getContentPane().add(startButton);
    }
}
ログイン後にコピー

このアプローチでは、SwingWorkers はタスクを同時に実行し、 Java 仮想マシン (JVM) はスレッド プールを管理し、タスクの実行をスケジュールします。すべての SwingWorker がタスクを完了すると、バリアがトリガーされ、GUI の更新を担当するバリアの run() メソッドが実行されます。

2. CountDownLatch

CountDownLatch は、特定の数のイベントが発生するまで複数のスレッドを待機できるようにするもう 1 つの同期メカニズムです。 SwingWorkers のコンテキストでは、次のように CountDownLatch を使用して、すべての SwingWorker がタスクを完了した後にのみ GUI が更新されるようにすることができます。

import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.*;
import javax.swing.*;

public class TestApplet extends JApplet {

    private static final int NUM_WORKERS = 10;
    private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(NUM_WORKERS);
    private static final CountDownLatch LATCH = new CountDownLatch(NUM_WORKERS);

    @Override
    public void init() {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    createGUI();
                }
            });
        } catch (InterruptedException | InvocationTargetException ex) {
        }
    }

    private void createGUI() {
        JButton startButton = new JButton("Do work");
        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                for (int i = 0; i < NUM_WORKERS; i++) {
                    EXECUTOR.submit(new SwingWorker<Void, Void>() {

                        @Override
                        protected Void doInBackground() throws Exception {
                            // Do some work
                            return null;
                        }

                        @Override
                        protected void done() {
                            LATCH.countDown();
                        }
                    });
                }
            }
        });
        getContentPane().add(startButton);
    }

    private void updateGUI() {
        // Update the GUI
    }

    @Override
    public void run() {
        try {
            LATCH.await();
            updateGUI();
        } catch (InterruptedException ex) {
        }
    }
}
ログイン後にコピー

このアプローチでは、SwingWorkers がタスクを実行します。同時に実行され、JVM はスレッド プールを管理し、タスクの実行をスケジュールします。すべての SwingWorker がタスクを完了すると、ラッチ カウントが 0 に達し、アプレットの run() メソッドが実行を継続して GUI を更新できるようになります。

3.フェイザー

フェイザーは同期です

以上が複数の同時実行 SwingWorkers の完了を調整するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート