0

多くのスレッドを実行していますが、特定のスレッド (TimerTask の run() メソッド) を実行して完了するまで実行したいので、他のスレッドによる中断は避けたいと考えています。

synchronized(this) { } はその完了を保証しないと思います。

これを行う正しい方法を教えてください。

4

3 に答える 3

0

一般に、スレッドが「中断」されるのを防ぐことはできませんが、これは計算がキャンセルされるという意味ではありません。スリープ/待機操作が例外をスローするだけです。javadocを参照してください。

その時点で終了したくない場合は、InterruptedException をキャッチして飲み込むことができます。

于 2012-09-21T08:12:43.967 に答える
0

「実際には、完了まで実行したいクリティカル スレッドの 1 つが実行されません。ログは、他のスレッドがタイム スライスを取得していることを示しており、クリティカルはその後続行されません。」

これは、OS のスケジューリングの問題とはまったく思えません。「クリティカルスレッド」がブロックされているか、何らかの例外のために終了したように聞こえます。

繰り返し実行すると、重要なスレッドが別の実行ポイントで停止することが示唆されます

  • ブロック状というより例外的に聞こえます。

私が間違っていて、コアよりも多くの準備ができているスレッドがあるためにクリティカル スレッドがプリエンプトされている場合は、クリティカル スレッドがプリエンプトされないように、クリティカル スレッドの優先度を上げる必要があります (または、ボックスの負荷を減らすだけです:) .

他の唯一の可能性は、スレッドが大量のデータを使用しており、多くのページ フォールトが発生していることです。この場合、より多くの RAM、SSD、またはその両方を入手してください!

于 2012-09-24T09:41:09.963 に答える
0

作業が完了したら、ステータスをキャッチInterruptedExceptionして設定できます。interrupt

キャンセル不可のタスク

一部のタスクは単に中断されることを拒否するため、キャンセルできなくなります。ただし、キャンセル不可能なタスクが完了した後、コール スタックの上位にあるコードが割り込みに対処したい場合に備えて、キャンセル不可能なタスクでも割り込みステータスを保持しようとする必要があります。リスト 6 は、アイテムが中断されたかどうかに関係なく、アイテムが使用可能になるまでブロッキング キューで待機するメソッドを示しています。良き市民になるために、呼び出し元から割り込み要求を奪わないように、終了後に finally ブロックで割り込み状態を復元します。(無限ループが発生するため、中断されたステータスを以前に復元することはできません。BlockingQueue.take() は、開始時にすぐに中断されたステータスをポーリングし、中断されたステータス セットが見つかった場合は InterruptedException をスローします。)

public Task getNextTask(BlockingQueue<Task> queue) {
boolean interrupted = false;
try {
    while (true) {
        try {
            return queue.take();
        } catch (InterruptedException e) {
            interrupted = true;
            // fall through and retry
        }
    }
} finally {
    if (interrupted)
        Thread.currentThread().interrupt();
}
}
于 2012-09-21T08:17:11.967 に答える