8

n 個のスレッドを並行して実行しており、それぞれがいくつかのカスタム ロジックを実行しています。ただし、私の要件は、スレッドのいずれかが実行を終了すると、他のすべてのスレッドが実行を停止して戻る必要があるということです。

これを実装する最良の方法は何ですか? 共有ブール変数を持つことでこれを行うことを考えました。いずれかのスレッドが実行を終了すると、ブール値が設定されます。すべてのスレッドは定期的にこの変数を読み取り、設定されている場合は終了します。

また、私のカスタム ロジックは無限ループであり、他のスレッドが実行を終了したことがわかったらすぐに、現在の反復後に実行を停止したいと考えています。

これを行う適切な方法は何ですか?

4

3 に答える 3

1

共通のセマフォを使用して実行を制御し、スレッドを頻繁にチェックしたいと思います。

public class MyTask implements Runnable {
    private static volatile boolean isDone = false
    @Override
    public void run() {
        while(true) {
            if (isDone) {
                break;
            }

            // do some calculation, no wait() s

            if (...has result...) {
                isDone = true;
                break;
            }
        }
    }
}

Thread t1 = new Thread(new MyTask());
Thread t2 = new Thread(new MyTask());
Thread t3 = new Thread(new MyTask());
t1.start();
t2.start();
t3.start();

注意しなければならないのはstatic volatile boolean変数だけです。すべてのスレッドが同じフラグにアクセスする必要があるためstaticであり、JVM がデータをキャッシュしないようにするためにvolatileです。揮発性としてマークしない場合、コンパイラは、フィールドを一度だけ読み取るようにフィールドからの読み取りを最適化し、ループ実行ごとに保存された値を使用するようなバイトコードを生成する場合があります。

タスクが異なり、異なるループを実装する場合、任意の外部public static volatile booleanフィールドを使用してフラグを保持できます。

この解決策は、スレッドの待機状態に依存しません。ループ内の複数の場所をチェックできます (すべてのコード ブロックの前でも)。コードが終了チェックに到達することが保証されている場合は、スレッドを中断する必要はありません。isDone

于 2013-06-18T13:23:55.050 に答える