4

私の Java アプリケーションには、並列化できる 2 つのサーバー呼び出しを必要とするロード タスクがあります。そこで、スレッド t1 ( task1を実行) とスレッド t2 ( task2用) を起動します。次に、他の両方のタスク (1 と 2) が終了したときに、特定のタスクtask3を実行したいと考えています。当然、タスク 1とタスク 2のどちらが先に終了するかわかりません...

これをコーディングする最も簡単な(そして最も安全な)方法はどれですか?

ご協力ありがとうございました

4

4 に答える 4

7

いくつかのオプションがあります:

  1. task3 が別のスレッド上にあり、かつ task1 と task2 のスレッドがそれらのタスク専用であり (スレッド プーリングなし)、タスクが終了すると終了する場合は、{T1.join(); を使用できます。T2.join();} を使用して、両方のスレッドを待機します。長所:簡単。短所: 状況がそれほど単純になることはめったにありません。
  2. task3 が別のスレッドにある場合は、すべてのスレッド間で共有される java.util.concurrent.CountDownLatch を使用できます。タスク 3 はラッチを待機し、タスク 1 とタスク 2 はラッチを減らします。長所: 非常に簡単で、環境を気にしません。短所: 本当に必要になる前に T3 を作成する必要があります。
  3. task1 と task2 が終了した後にのみ task3 を作成する必要がある場合 (task1 と task2 が終了するまで個別のスレッドがない)、もう少し複雑なものを作成する必要があります。フューチャに条件 n を追加してフューチャを実行する独自の ExecutorService を作成するか、条件が変更された場合にのみフューチャを実行するか、条件をチェックしてこれらの条件に基づいて特定のフューチャを送信する管理サービスを作成することをお勧めします。心に留めておいてください、これは私の頭の中です。もっと簡単な解決策があるかもしれません。長所:資源に優しい。短所:複雑。
于 2008-10-08T07:59:20.043 に答える
2

および(いずれかの順序で)join両方を実行してから、結合後に task3 を実行できます。t1t2

于 2008-10-08T07:34:44.803 に答える
0

task3 にリスナー インターフェイスを実装し、それを task1 と task2 の両方に登録します。Task1 と Task2 は、終了直前にリスナーを呼び出す必要があります。そうすることで、すでに終了したタスクを task3 に記録し、両方が終了したら、3 つ目のタスクを実行できます。

もちろん、タスク 1/2 のいずれかが例外で終了する可能性がある場合は、タスク 3 をその UncaughtExceptionHandler として配置することを忘れないでください。

于 2008-10-08T07:48:10.737 に答える
0

2 つのワーカー スレッド (task1 と task2) がジョブを終了したときに終了させたくない場合は、他の 2 つが終了するまで task3 の条件で待機できます。このようなもの:

public class Master {

    private Object monitor_ = new Object();
    private boolean task1Finished_;
    private boolean task2Finished_;

    class Task1 extends Thread {

        public void run() {
            // do stuff
            synchronized (monitor_) {
                task1Finished_ = true;
                monitor_.notifyAll();
            }
            // keep on working
        }
    }

    class Task2 extends Thread {

        public void run() {
            // do stuff
            synchronized (monitor_) {
                task1Finished_ = true;
                monitor_.notifyAll();
            }
            // keep on working
        }
    }

    class Task3 extends Thread {

        public void run() {
            synchronized (monitor_) {
                while (!task1Finished_ || !task2Finished_) {
                    try {
                        monitor_.wait();
                    }
                    catch (InterruptedException ignored) {
                    }
                }
            }
            // do stuff
        }
    }
    // start tasks1, task2 and task3...
}
于 2008-10-08T07:49:34.413 に答える