ホームページ  >  記事  >  Java  >  Javaスレッド割り込みタイムアウト例外(InterruptedTimeoutException)の解決方法

Javaスレッド割り込みタイムアウト例外(InterruptedTimeoutException)の解決方法

PHPz
PHPzオリジナル
2023-08-22 09:51:311526ブラウズ

Javaスレッド割り込みタイムアウト例外(InterruptedTimeoutException)の解決方法

Java スレッド割り込みタイムアウト例外 (InterruptedTimeoutException) を解決する方法

はじめに:
並行プログラミングでは、スレッド割り込み操作は非常に一般的な技術手段です。実行する必要がなくなったスレッドを終了したり、複数のスレッド間を調整したりするために使用できます。ただし、スレッドの中断が必ずしもスムーズに完了するとは限らず、中断タイムアウトが発生する場合があります。この記事では、Java スレッド割り込みタイムアウト例外 (InterruptedTimeoutException) を解決する方法と、関連するコード例を紹介します。

1. 割り込みタイムアウトの原因の分析:
スレッド割り込み操作は通常、非同期操作です。つまり、スレッド割り込みフラグはすぐに true に設定されますが、スレッドがすぐにタイムアウトするわけではありません。実行を停止します。スレッドが正常に中断できるかどうかは、スレッド自体の設計と現在の実行ステータスによって異なります。スレッドを中断して一定時間内にスレッドが停止するのを待つ必要がある場合、スレッドが指定時間内に実行を停止できなかった場合、割り込みタイムアウト例外 (InterruptedTimeoutException) がスローされます。

2. 解決策:
Java スレッド割り込みタイムアウト例外を解決する主な方法は次のとおりです:

  1. Thread.join (長いタイムアウト) メソッドを使用します:
    Thread クラスの join(long timeout) メソッドを使用してスレッドを待つことができます。呼び出し側スレッドがこのメソッドを実行した後、呼び出されたスレッドが終了するか、指定されたタイムアウトに達するまで待機します。スレッドがタイムアウト期間内に終了した場合は true を返し、それ以外の場合は false を返します。この方法により、スレッド中断タイムアウト状況を効果的に解決できます。

サンプル コードは次のとおりです。

Thread thread = new Thread(() -> {
    // 线程执行的逻辑代码
});

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

try {
    thread.join(1000); // 线程最多等待1秒钟
} catch (InterruptedException e) {
    // 处理中断异常
}

if (thread.isAlive()) {
    thread.interrupt(); // 如果线程还未结束,手动中断
}
  1. Future.get(long timeout, TimeUnit Unit) メソッドを使用します。
    別の解決策は、Java を使用することです。同時実行ライブラリ Future と ExecutorService。 Future インターフェースは非同期計算の結果を表し、get(long timeout, TimeUnit Unit) メソッドでタイムアウトを設定できます。指定されたタイムアウト期間内にタスクが完了しない場合、タイムアウト例外がスローされ、操作が中断されます。

サンプル コードは次のとおりです:

ExecutorService executor = Executors.newSingleThreadExecutor();

Future<?> future = executor.submit(() -> {
    // 线程执行的逻辑代码
    // 注意,此处不能使用while循环等待线程中断,否则可能导致线程无法正确中断
});

try {
    future.get(1000, TimeUnit.MILLISECONDS); // 最多等待1秒钟
} catch (InterruptedException | ExecutionException | TimeoutException e) {
    // 处理中断异常
    future.cancel(true); // 如果超时,手动取消任务
}

executor.shutdown(); // 关闭线程池
  1. 割り込みフラグと待機タイムアウト メカニズムをカスタマイズします:
    特殊なケースでは、割り込みのカスタマイズが必要になる場合があります。フラグと待機タイムアウトのメカニズム。 volatile で変更されたブール型変数を割り込みフラグとして使用し、スレッドの実行中にポーリングしてフラグを決定し、タイムアウト条件が満たされたときに手動でスレッドを割り込むことができます。

サンプル コードは次のとおりです:

volatile boolean interrupted = false;

Thread thread = new Thread(() -> {
    while (!interrupted) {
        // 线程执行的逻辑代码
    }
});

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

try {
    Thread.sleep(1000); // 等待1秒钟
} catch (InterruptedException e) {
    // 处理中断异常
}

interrupted = true; // 设置中断标志

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

概要:
上記は、Java スレッドの割り込みタイムアウト例外 (InterruptedTimeoutException) を解決するための 3 つの一般的な方法です。 Thread.join() メソッド、Future.get() メソッド、またはカスタムの割り込みフラグと待機タイムアウトのメカニズムを使用することにより、スレッド割り込み操作のタイムアウトによって引き起こされる例外を回避し、柔軟で信頼性の高いスレッド割り込みを実現できます。

ただし、スレッド割り込み操作を使用する場合は、スレッドの安全で信頼性の高い操作を確保するために、デッドロックや競合状態などの同時実行性の問題を回避することにも注意する必要があります。

参考資料:

  1. Oracle 公式ドキュメント - https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
  2. Oracle 公式ドキュメント - https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html

以上がJavaスレッド割り込みタイムアウト例外(InterruptedTimeoutException)の解決方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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