web-dev-qa-db-ja.com

実行可能なインターフェースを実装することで作成されたスレッドを停止する方法は?

実行可能なインターフェイスを実装してクラスを作成し、プロジェクトの他のクラスに多くのスレッド(10個近く)を作成しました。
これらのスレッドのいくつかを停止する方法は?

53
svkvvenky

simplestの方法はinterrupt() itで、これはThread.currentThread().isInterrupted()trueを返し、投げることもありますスレッドがwaitingである特定の状況下でのInterruptedException、たとえばThread.sleep()otherThread.join()object.wait()など.

run()メソッド内では、その例外をキャッチするか、定期的にThread.currentThread().isInterrupted()値をチェックして何かを実行する必要があります(たとえば、ブレークアウト)。

注:Thread.interrupted()isInterrupted()と同じように見えますが、副作用があります:interrupted()clearsinterruptedフラグを呼び出しますが、isInterrupted()しません。

他の中断しない方法には、実行中のスレッドが監視する「停止」(volatile)フラグの使用が含まれます。

72
Bohemian

実行可能なインターフェースを実装することで作成されたスレッドを停止する方法は?

スレッドを停止するには多くの方法がありますが、それらはすべて特定のコードを使用して停止できます。スレッドを停止する一般的な方法は、スレッドが頻繁にチェックするvolatile boolean shutdownフィールドを持つことです。

  // set this to true to stop the thread
  volatile boolean shutdown = false;
  ...
  public void run() {
      while (!shutdown) {
          // continue processing
      }
  }

sleep()wait()、およびその他のメソッドがInterruptedExceptionをスローする原因となるスレッドを中断することもできます。また、次のような方法でスレッド割り込みフラグをテストする必要があります。

  public void run() {
      while (!Thread.currentThread().isInterrupted()) {
          // continue processing
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              // good practice
              Thread.currentThread().interrupt();
              return;
          }
      }
  }

interrupt()を使用してスレッドを中断すると、notが必ず例外をすぐにスローすることに注意してください。割り込み可能なメソッドを使用している場合のみ、InterruptedExceptionがスローされます。

Runnableを実装するクラスにshutdown()メソッドを追加する場合は、次のように独自のクラスを定義する必要があります。

public class MyRunnable implements Runnable {
    private volatile boolean shutdown;
    public void run() {
        while (!shutdown) {
            ...
        }
    }
    public void shutdown() {
        shutdown = true;
    }
}
35
Gray

停止中途中のスレッドはお勧めできません。より適切な方法は、プログラムからスレッドを返すことです。 Runnableオブジェクトがrun()メソッドで共有変数を使用するようにします。スレッドを停止する場合は常に、その変数をフラグとして使用します。

編集:サンプルコード

class MyThread implements Runnable{

    private Boolean stop = false;

    public void run(){

        while(!stop){

            //some business logic
        }
    }
    public Boolean getStop() {
        return stop;
    }

    public void setStop(Boolean stop) {
        this.stop = stop;
    }       
}

public class TestStop {

    public static void main(String[] args){

        MyThread myThread = new MyThread();
        Thread th = new Thread(myThread);
        th.start();

        //Some logic goes there to decide whether to 
        //stop the thread or not. 

        //This will compell the thread to stop
        myThread.setStop(true);
    }
}
9
Santosh

ThreadPoolExecutorを使用し、 submit() メソッドを使用すると、Futureが返されます。返されたFutureで cancel() を呼び出して、Runnableタスクを停止できます。

6
Kuldeep Jain

スレッドを途中で停止(キリング)することはお勧めしません。 APIは実際には非推奨です。

ただし、回避策を含む詳細をここで取得できます: Javaでスレッドをどのように強制終了しますか?

1
vaisakh

Thread.currentThread()。isInterrupted()は非常に機能しています。ただし、このコードはタイマーを一時停止するだけです。

このコードは停止し、スレッドタイマーをリセットします。h1はハンドラー名です。このコードは、ボタンクリックリスナー内に追加されます。 w_h =分w_m =ミリ秒i =カウンター

 i=0;
            w_h = 0;
            w_m = 0;


            textView.setText(String.format("%02d", w_h) + ":" + String.format("%02d", w_m));
                        hl.removeCallbacksAndMessages(null);
                        Thread.currentThread().isInterrupted();


                        }


                    });


                }`
0
Anish