1

ループ内で実行されているスレッドを安全に停止し、最後のループを終了してから制御をストッパーに戻すメソッドを作成したいと考えています。

今、何をしようとしてもフリーズします。おそらくデッドロックなどから抜け出します。Java は私の通常の環境ではないため、これがさらに別の待機/通知の質問になる可能性があるのはなぜですか。

boolean isRunning = true;

@Override
public void run() {
    super.run();

    while (isRunning) {
        // Do work...
    }

    synchronized(this) {
        this.notify();
    }
}

public void stopSafely() {
    isRunning = false;

    try {
        synchronized(this) {
            this.wait();
        }
    } catch (InterruptedException ex) {
        // Handle...
    }
}

このアプローチの問題は ( で同期するという事実は別としてthis、例を簡単にするためです)、のnotify前に呼び出された場合wait、呼び出し元がフリーズすることです。

私が囲んでいるブロックで遊んでsynchronized問題を解決できると確信していますが、正しい組み合わせが得られないようです.

何か案が?

4

4 に答える 4

2

本当に簡単な解決策を探してください:

private volatile boolean isRunning = true;

@Override
public void run() {
    while (isRunning) {
        // Do work...
    }
}

public void stopThread() {
    isRunning = false;
}

これは基本的にThread.interrupted()内部で行うことなので、これも使用できます。

@Override
public void run() {
    while (Thread.interrupted()) {
        // Do work...
    }
}

その場合interrupt()、スレッドで呼び出す必要があります。

于 2011-12-09T03:49:23.143 に答える
1

2 番目のメソッドが、run メソッドを持つスレッドとは別のスレッドから呼び出されることを願っています。きっとそうだ。

この場合、同期ブロック内に isRunning=false を配置するだけで十分です。特定のモニターで同期されたブロックに入ることができるスレッドは 1 つだけです。

ところで、super.run() を呼び出さないでください。役に立たず、良いプログラミングの習慣ではありません。

于 2011-12-09T03:17:09.597 に答える
0

まず make isRunning volatile から始めます。

volatile boolean isRunning = true;

問題は、Java ランタイムが何らかの最適化を行い、最初のスレッドが値を変更したにもかかわらず、値が他のスレッドに反映されないことです。

于 2011-12-09T03:17:14.327 に答える
0

変更を行うときにチェックすることを単に妨げる、はるかに単純な解決策を見つけましたisRunning

boolean isRunning = true;

@Override
public void run() {
    while (true) {
        synchronized(this) {
            if (!isRunning) break;
        }

        // Do work...
    }
}

public void stopSafely() {
    synchronized(this) {
        isRunning = false;
    }
}
于 2011-12-09T03:16:04.080 に答える