26
Thread currentThread=Thread.currentThread();
        public void run()
        {               

             while(!shutdown)
            {                               
                try
                {
                    System.out.println(currentThread.isAlive());
                Thread.interrupted();

                System.out.println(currentThread.isAlive());
                if(currentThread.isAlive()==false)
                {
                    shutdown=true;
                }
                }
                catch(Exception e)
                {
                    currentThread.interrupt();
                }                   
            }
        }

    });
    thread.start();
4

3 に答える 3

61

stop を呼び出す代わりに、interrupt を使用して、実行中の処理を終了するようにスレッドに通知することもできます。(これは、停止したいスレッドが適切に動作していることを前提としています。InterruptedExceptions がスローされた直後にそれらを食べることによってそれらを無視し、中断されたステータスをチェックしない場合は、stop() の使用に戻ります。)

これは、スレッドの質問hereへの回答として私が書いたコードです。これは、スレッドの中断がどのように機能するかの例です。

public class HelloWorld {

    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(new Runnable() {

            public void run() {
                try {
                    while (!Thread.currentThread().isInterrupted()) {
                        Thread.sleep(5000);
                        System.out.println("Hello World!");
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        thread.start();
        System.out.println("press enter to quit");
        System.in.read();
        thread.interrupt();
    }
}

次の点に注意してください。

  • sleep()原因を中断wait()し、すぐにスローします。そうしないと、スリープ時間が経過するのを待って立ち往生します。

  • 個別のブール フラグは必要ないことに注意してください。

  • 停止中のスレッドは、中断されたステータスをチェックし、while ループの外側で InterruptedExceptions をキャッチすることによって連携します (それを使用してループを終了します)。割り込みは、フロー制御に例外を使用しても問題ない場所の 1 つであり、それが全体のポイントです。

  • catch ブロックで現在のスレッドに割り込みを設定することは、技術的にはベスト プラクティスですが、割り込みフラグを設定する必要があるものは他にないため、この例ではやり過ぎです。

投稿されたコードに関するいくつかの観察:

  • 投稿された例は不完全ですが、現在のスレッドへの参照をインスタンス変数に入れるのは悪い考えのようです。run メソッドを実行しているスレッドではなく、オブジェクトを作成しているスレッドに初期化されます。同じ Runnable インスタンスが複数のスレッドで実行される場合、ほとんどの場合、インスタンス変数は正しいスレッドを反映しません。

  • スレッドが生きているかどうかのチェックは、常に true になります (currentThread インスタンス変数が間違ったスレッドを参照しているエラーがない限り)。Thread#isAliveスレッドの実行が終了した後にのみ false になります。単に false を返すことはありません。中断されたからです。

  • 呼び出すThread#interruptedと、割り込みフラグがクリアされ、特に戻り値が破棄されるため、ここでは意味がありません。呼び出しのポイントはThread#interrupted、割り込みフラグの状態をテストしてからクリアすることです。これは、スローするものによって使用される便利なメソッドInterruptedExceptionです。

于 2011-05-06T18:06:41.560 に答える
14

通常、スレッドは中断されると終了します。では、ネイティブブール値を使用してみませんか?isInterrupted()を試してください:

   Thread t = new Thread(new Runnable(){
        @Override
        public void run() {
            while(!Thread.currentThread().isInterrupted()){
                // do stuff         
            }   
        }});
    t.start();

    // Sleep a second, and then interrupt
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {}
    t.interrupt();
于 2011-05-06T18:18:52.360 に答える
6

これを行う良い方法は、ブールフラグを使用してスレッドに信号を送ることです。

class MyRunnable implements Runnable {

    public volatile boolean stopThread = false;

    public void run() {
            while(!stopThread) {
                    // Thread code here
            }
    }

}

myrunnableという名前のMyRunnableインスタンスを作成し、それを新しいThreadインスタンスでラップして、インスタンスを起動します。スレッドに停止のフラグを立てる場合は、myrunnable.stopThread=trueに設定します。このように、何かの途中で停止することはなく、停止することが予想される場所でのみ停止します。

于 2011-05-06T18:00:55.317 に答える