web-dev-qa-db-ja.com

JavaのThread.sleepはいつInterruptedExceptionをスローしますか?

JavaのThread.sleepはいつInterruptedExceptionをスローしますか?無視しても安全ですか?マルチスレッドは行っていません。数秒待ってから操作を再試行します。

106
Manki

通常、例外を無視しないでください。次の論文をご覧ください。

割り込みを飲み込まないでください

Runnableによって定義されたタスクが割り込み可能なメソッドを呼び出す場合など、InterruptedExceptionをスローすることはオプションではない場合があります。この場合、InterruptedExceptionを再スローすることはできませんが、何もしたくありません。ブロッキングメソッドが割り込みを検出し、InterruptedExceptionをスローすると、割り込み状態がクリアされます。 InterruptedExceptionをキャッチしても再スローできない場合は、割り込みが発生したという証拠を保存して、呼び出しスタックの上位のコードが割り込みを学習し、必要に応じてそれに応答できるようにする必要があります。このタスクは、リスト3に示すように、interrupt()を呼び出して現在のスレッドを「再割り込み」することによって達成されます。少なくとも、InterruptedExceptionをキャッチして再スローしない場合は、現在のスレッドを再割り込みしてから戻る必要があります。

public class TaskRunner implements Runnable {
    private BlockingQueue<Task> queue;

    public TaskRunner(BlockingQueue<Task> queue) { 
        this.queue = queue; 
    }

    public void run() { 
        try {
             while (true) {
                 Task task = queue.take(10, TimeUnit.SECONDS);
                 task.execute();
             }
         }
         catch (InterruptedException e) { 
             // Restore the interrupted status
             Thread.currentThread().interrupt();
         }
    }
}

こちらの論文全体をご覧ください。

http://www.ibm.com/developerworks/Java/library/j-jtp05236/index.html?ca=drs-

38

InterruptedExceptionがスローされた場合、何かがそのスレッドを中断(通常は終了)したいことを意味します。これは、スレッドinterrupt()メソッドの呼び出しによってトリガーされます。 waitメソッドはそれを検出してInterruptedExceptionをスローするため、キャッチコードは終了のリクエストをすぐに処理でき、指定された時間が経過するまで待つ必要はありません。

シングルスレッドアプリ(および一部のマルチスレッドアプリ)で使用すると、その例外はトリガーされません。空のcatch句を使用して無視することはお勧めしません。 InterruptedExceptionをスローすると、スレッドの中断状態がクリアされるため、適切に処理されない場合、その情報は失われます。したがって、私は実行することを提案します:

} catch (InterruptedException e) {
  Thread.currentThread().interrupt();
  // code for stopping current task so thread stops
}

その状態を再度設定します。その後、実行を終了します。これは正しい振る舞いであり、使用されることはありません。

より良いかもしれないのはこれを追加することです:

} catch (InterruptedException e) {
  throw new RuntimeException("Unexpected interrupt", e);
}

... catchブロックのステートメント。それは基本的に、決して起こらないことを意味します。そのため、発生する可能性のある環境でコードを再利用すると、文句を言うことになります。

34
Christian

Java Specialists newsletter(私はこれをお勧めできます))には これに関する興味深い記事 があり、InterruptedExceptionを処理する方法があります。そして消化。

12
Brian Agnew

シングルスレッドのコードでそれを処理するための堅実で簡単な方法は、すべてのメソッドで宣言する必要を回避するために、それをキャッチしてRuntimeExceptionに戻すことです。

3
starblue

クラスThreadsleep()wait()などのメソッドは、InterruptedExceptionをスローする場合があります。これは、他のthreadが待機中またはスリープ中のthreadを中断したい場合に発生します。

2
Anshika