ホームページ  >  記事  >  Java  >  Javaで実行中のスレッドを中断する方法(1)

Javaで実行中のスレッドを中断する方法(1)

黄舟
黄舟オリジナル
2016-12-30 13:19:451084ブラウズ

マルチスレッドは、プログラミング プロセス中にプログラマに一連の新たな問題をもたらします。実行中のスレッドを中断する方法も問題の 1 つです。この記事では、関連する方法について説明します。

手順はとても簡単です。ただし、マルチスレッドはプログラマーにとって新たな一連の課題をもたらし、適切に対処しないと、予期しない動作や発見が難しい微妙なエラーにつながる可能性があります。

この記事では、これらの問題の 1 つである、実行中のスレッドを中断する方法に取り組みます。

スレッドのバックグラウンド中断とは、スレッドがタスクを完了する前に実行中のすべてを停止し、現在の操作を効果的に中止することを意味します。スレッドが終了するか、新しいタスクを待つか、次のステップに進むかは、このプログラムによって異なります。最初は簡単に思えるかもしれませんが、望ましい結果を達成するには、いくつかの事前警告が必要です。次の警告に留意してください。

まず第一に、Thread.stop メソッドのことは忘れてください。ただし、実行中のスレッドは停止しますが、このメソッドは安全ではないため推奨されません。つまり、Java の将来のバージョンではこのメソッドは存在しなくなります。

一部の軽率な輩は別の方法 Thread.interrupt に騙されるかもしれません。ただし、その名前が暗示しているように見えますが、リスト A で説明されているように、このメソッドは実行中のスレッドを中断しません (これについては後で詳しく説明します)。スレッドを作成し、Thread.interrupt メソッドを使用してスレッドを停止しようとします。 Thread.sleep() メソッドを呼び出すと、スレッドの初期化と終了に十分な時間が与えられます。スレッド自体は有用な操作には参加しません。

class Example1 extends Thread {
            boolean stop=false;
            public static void main( String args[] ) throws Exception {
            Example1 thread = new Example1();
            System.out.println( "Starting thread..." );
            thread.start();
            Thread.sleep( 3000 );
            System.out.println( "Interrupting thread..." );
            thread.interrupt();
            Thread.sleep( 3000 );
            System.out.println("Stopping application..." );
            //System.exit(0);
            }
            public void run() {
            while(!stop){
            System.out.println( "Thread is running..." );
            long time = System.currentTimeMillis();
            while((System.currentTimeMillis()-time < 1000)) {
            }
            }
            System.out.println("Thread exiting under request..." );
            }
            }

リスト A のコードを実行すると、コンソールに次の出力が表示されます。

Starting thread...
Thread is running...
Thread is running...
Thread is running...
Interrupting thread...
Thread is running...
Thread is running...
Thread is running...
Stopping application...
Thread is running...
Thread is running...
Thread is running...
.....................

Thread.interrupt() が呼び出された後でも、スレッドは実行を続けます。

実際にスレッドを中断する

スレッドを中断する最良かつ最も推奨される方法は、共有変数を使用して、スレッドが実行中のタスクを停止する必要があることを通知することです。スレッドはこの変数を定期的にチェックし (特に冗長操作中)、順序どおりにタスクを終了する必要があります。リスト B はこのアプローチを説明しています。

Listing B
class Example2 extends Thread {
  volatile boolean stop = false;
  public static void main( String args[] ) throws Exception {
    Example2 thread = new Example2();
   System.out.println( "Starting thread..." );
   thread.start();
   Thread.sleep( 3000 );
   System.out.println( "Asking thread to stop..." );
   thread.stop = true;
   Thread.sleep( 3000 );
   System.out.println( "Stopping application..." );
   //System.exit( 0 );
  }
  public void run() {
    while ( !stop ) {
     System.out.println( "Thread is running..." );
      long time = System.currentTimeMillis();
      while ( (System.currentTimeMillis()-time < 1000) && (!stop) ) {
      }
    }
   System.out.println( "Thread exiting under request..." );
  }
}

リスト B のコードを実行すると、次の出力が生成されます (スレッドがどのように正常に終了するかに注目してください)

Starting thread...
Thread is running...
Thread is running...
Thread is running...
Asking thread to stop...
Thread exiting under request...
Stopping application...

このメソッドにはコーディングが必要ですが、実装は難しくありません。同時に、スレッドに必要なクリーンアップ作業を実行する機会を与えます。これはマルチスレッド アプリケーションでは絶対に必要です。共有変数を揮発性として定義するか、共有変数へのすべてのアクセスを同期されたブロック/メソッドで囲むようにしてください。

今のところとても順調です!しかし、スレッドが何らかのイベントの発生を待ってブロックされている場合はどうなるのでしょうか?もちろん、スレッドがブロックされている場合、共有変数を確認することはできず、停止することはできません。これは、たとえば Object.wait()、ServerSocket.accept()、DatagramSocket.receive() を呼び出すときなど、多くの状況で発生します。

それらはすべて、スレッドを永久にブロックする可能性があります。タイムアウトが発生した場合でも、タイムアウトが経過する前に待機し続けることは現実的ではなく、適切ではないため、スレッドがブロック状態を早期に終了できるようにするための何らかのメカニズムを使用する必要があります。

残念ながら、すべての状況で機能するそのようなメカニズムはありませんが、状況に応じて特定のテクニックを使用できます。次のリンクでは、最も一般的な例に答えます。

上記は、Java で実行中のスレッドを中断する方法 (1) の内容です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。