ホームページ  >  記事  >  Java  >  Javaのスレッド割り込みとは何ですか? Java スレッドの中断によりどのような問題が発生しますか?

Javaのスレッド割り込みとは何ですか? Java スレッドの中断によりどのような問題が発生しますか?

不言
不言オリジナル
2018-09-20 15:00:023445ブラウズ

この記事の内容は、Java におけるスレッド中断とは何ですか? Java スレッドの中断によりどのような問題が発生しますか?困っている友人は参考にしていただければ幸いです。

スレッド割り込みとは何ですか?

実際、Java プログラムには複数の実行スレッドがあります。すべてのスレッドの実行が終了した場合にのみ、Java プログラムは終了したとみなされます。公式の説明は次のとおりです。この Java プログラムは、すべての非デーモン スレッドの実行が終了したとき、またはスレッドの 1 つが System.exit() メソッドを呼び出したときに終了します。

スレッド中断のアプリケーション シナリオ

最初に例を示します。たとえば、500M を超える大作をダウンロードする場合、この時点ではクリックしてダウンロードを開始します。スレッドを開始してください。ただし、現時点では、数十 KB のファイルが実行されているため、これ以上ダウンロードすることはできません。 、この時点での最初の操作はダウンロードを終了することです。このとき、実際にはプログラムに近い操作です。

次に、スレッドを中断する方法を確認するためにダウンロード コードを作成しましょう。ここでは、このプログラムでダウンロードをシミュレートする方法を習得したことを前提としています。最初にシステム時間を取得し、その後毎回システム時間を取得するループに入ります。時間が 10 秒を超えると、スレッドが中断され、ダウンロードは続行されません:

public void run() {

       int number = 0;

       // 记录程序开始的时间
       Long start = System.currentTimeMillis();

       while (true) {

           // 每次执行一次结束的时间
           Long end = System.currentTimeMillis();

           // 获取时间差
           Long interval = end - start;

           // 如果时间超过了10秒,那么我们就结束下载
           if (interval >= 10000) {
               // 中断线程
               interrupted();
               System.err.println("太慢了,我不下了");
               return;
           } else if (number >= 500) {
               System.out.println("文件下载完成");
               // 中断线程
               interrupted();
               return;
           }

           number++;
           System.out.println("已下载" + number + "M");

           try {
               Thread.sleep(2000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
   }

スレッドを中断する方法

Thread クラスは、スレッドを中断するメソッドを提供します。まず、このメソッドがスレッドを中断する方法を見てみましょう。

public static boolean interrupted() { 
      return currentThread().isInterrupted(true);
   }

これは、現在のスレッドが中断された場合は true を返し、中断されなかった場合は false を返すかどうかを確認するメソッドです。


private native boolean isInterrupted(boolean ClearInterrupted);

ソース コードを見ると、スレッドが中断されていることがわかります。 thread は、スレッドが中断されているかどうかを確認するメソッドを呼び出し、値を true に設定します。このとき、スレッドが中断されているかどうかを確認するためにメソッドを呼び出すと、true が返されます。

誰もがここでの問題に注意する必要があります。Thread.interrupted() メソッドは現在のスレッドのステータスを変更して割り込みを指示するだけですが、ブロックされていないスレッドの場合は割り込みを変更するだけです。ステータス、つまり Thread.isInterrupted () は true を返します。これらの関数 Thread.sleep() を待機しているスレッドなど、キャンセル可能なブロック状態にあるスレッドの場合、このスレッドは割り込み信号を受信した後、InterruptedException をスローします。同時にステータスが true に設定されます。

スレッドスリープによって InterruptedException が発生する理由

実はこれについては皆さんも少しは理解しているので、間違った例を書いてみます。この問題を徹底的に解決してください:

public void run() {

       int number = 0;

       while (true) {
           // 检查线程是否被中断,中断就停止下载
           if (isInterrupted()) {

               System.err.println("太慢了,我不下了");
               return;
           } else if (number >= 500) {
               System.out.println("下载完成");
               return;
           }

           number++;
           System.out.println("已下载" + number + "M");

           try {
               Thread.sleep(2000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
   }

これは私たちのメイン プログラムです。10 秒待ってからスレッドを中断します。

public static void main(String[] args) throws InterruptedException {

       Thread thread = new PrimeGenerator();

       // 启动线程
       thread.start();

       // 等待10秒后中断线程
       Thread.sleep(1000);

       // 中断线程
       thread.interrupt();
   }

これは非常に普通のプログラムのように見えますが、実際は実際、このコード部分は InterruptedException をスローします。その理由を分析してみましょう。

ここでは、Thread.sleep() メソッドが呼び出されても、Thread.interrupt() メソッドは実行中のスレッドを中断しないことを最初に理解する必要があります。この時点で CPU が占有されています。ダウンロードするのに 10 秒かかります。つまり、5M までダウンロードすると待ち時間が終了します。このとき、Thread.interrupt() メソッドを呼び出してスレッドを中断しますが、 run() メソッドのスリープは引き続き実行され、中断によって次のコードの実行が中断されることはありません。 Thread.sleep() を再度実行すると、現在のスレッドが中断されたため、InterruptedException がスローされます。

そういえば、この例外の理由はもうわかりましたか?さらに、スレッドが InterruptedException 例外を生成する理由は他にも 2 つあります。 wait() メソッドと join() メソッドを不適切に使用すると、スレッドがこの例外をスローする可能性もあります。

スレッドが中断されているかどうかを確認する 2 つの方法

Thread クラスには、現在のスレッドがいつ中断されたかを確認するために使用できるメソッド Interrupted() があります。 、および isInterrupted() メソッドを使用して、現在のスレッドが中断されているかどうかを確認できます。

スレッドを中断する基本的な方法は、このプロパティを true に設定することであり、isInterrupted() メソッドはプロパティ値を返すだけです。

これら 2 つのメソッドの違いの 1 つは、isInterrupted() は Interrupted() の属性値を変更できないが、interrupted() メソッドは Interrupted の属性値を変更できることです。したがって、スレッドがいつ中断されたかを判断するときは、isInterrupted() を使用することをお勧めします。

以上がJavaのスレッド割り込みとは何ですか? Java スレッドの中断によりどのような問題が発生しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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