15

スレッドプール内のすべてのスレッドを閉じようとしています。

通常、私は試します:

        while(!Thread.currentThread().isInterrupted()) {...

while ループを閉じるには...

しかし、私は約からなるスレッドを1つ持っています

        while(!Thread.currentThread().isInterrupted()) {//which is true

これは私がスレッドを閉じる方法です:

pool.shutdownNow();

では、そのようなスレッドをどのように閉じるのでしょうか?

4

4 に答える 4

16

volatileブール値を追加できますflag

public class Worker implements Runnable {

    volatile boolean cancel = false;
    @Override
    public void run() {

        while (!cancel) {
            // Do Something here
        }
    }

    public void cancel() {
        cancel = true;
    }
}

今、あなたはただ電話することができます

worker.cancel();

アップデート:

shutdownNow()の Java doc から

アクティブに実行中のすべてのタスクの停止を試み、待機中のタスクの処理を停止し、実行を待機していたタスクのリストを返します。

ここでは、アクティブに実行中のタスクの処理を停止するための最善の試みを超える保証はありません。たとえば、典型的な実装はThread.interrupt()によってキャンセルされるため、割り込みに応答しないタスクは決して終了しない可能性があります。

したがって、割り込みを保持して割り込みポリシーを定義する必要があります

  catch (InterruptedException ie) {
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
于 2012-10-29T10:56:54.877 に答える
2

その代わりに、while ループの条件として自己作成フラグを使用できます。

public class MyClass implements Runnable
{

    private volatile boolean running = true;

    public void stopRunning()
    {
        running = false;
    }

    public void run()
    {
        while (running)
        {

        }
        // shutdown stuff here
    }

}

停止するには、次のように呼び出します。

myClassObject.stopRunning();

これにより、コードが正常に終了します。

于 2012-10-29T10:55:38.677 に答える
2

あなたが説明したようにこれを実装した場合、それはうまくいくはずです。

呼び出すpool.shutdownNow()と、現在アクティブなすべてのワーカー スレッドを中断することになっています。run()アプリケーション固有のメソッドが中断されたフラグをチェックし、フラグが設定されていることを検出したときに終了すると仮定すると、スレッドはシャットダウンする必要があります。

アドホックキャンセル フラグなどを使用して別のメカニズムを追加する必要はまったくありません。


ちなみに、アドホックキャンセルinterrupt()よりも優れている理由がいくつかあります。

  • ExecutorService などの標準 API で使用されます。
  • sleepwait、および一部の I/O メソッドなどのさまざまな低レベル API メソッドは、joinそれに敏感です。
于 2012-10-29T11:09:27.137 に答える
1

java.util.concurrentExecutorService 実装を使用している場合interrupt、スレッド プール内のすべてのスレッドに確実にシグナルが送信されます。不正なタスクの問題は、ループが実際には繰り返されず、ループ内のどこかでブロックされるため、interruptedステータスがまったくチェックされないことです。

さらに別の問題が発生する可能性があります。while ループは、適切に処理せずにInterruptedException をキャッチするコードを実行し、実質的に割り込みシグナルを飲み込んでしまいます。InterruptedExceptionこれはよくあるコーディングの間違いであり、ほとんどの場合、チェックされる醜い真実が原因です。

于 2012-10-29T11:08:38.287 に答える