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


110

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



1
どの意味で「無視」を意味するかによります。InterruptedExceptionあなたが扱う場合を除き、コンパイルや結合または眠るいずれかの方法で例外のこの型を宣言することはできませんので、キャッチした例外は、あるThread、または通話wait()Object
8bitjunkie 2014

回答:


41

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

割り込みを飲み込まない

Rundableによって定義されたタスクが割り込み可能なメソッドを呼び出す場合など、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スローされ、それはその何かが(通常は終了)、そのスレッドを中断したいことを意味します。これは、threads interrupt()メソッドの呼び出しによってトリガーされます。waitメソッドはそれを検出してをスローするInterruptedExceptionので、catchコードは終了の要求をすぐに処理でき、指定された時間が経過するまで待機する必要はありません。

シングルスレッドアプリ(および一部のマルチスレッドアプリ)で使用する場合、その例外はトリガーされません。空の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ブロックへのステートメント。それは基本的にそれが決して起こらないことを意味します。したがって、コードが発生する可能性のある環境でコードが再利用されると、それについて不満が出ます。


5
Javaのアサーションはデフォルトでオフになっています。したがって、単にをスローする方が良いでしょうRuntimeException
Evgeni Sergeev 2016年


5

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


3

シングルスレッドコードでこれを処理する確実で簡単な方法は、それをキャッチし、RuntimeExceptionで後処理することです。これにより、すべてのメソッドで宣言する必要がなくなります。


-7

InterruptedException睡眠が中断されたときに、通常はスローされます。


13
中断されるのはスリープ自体ではなく、スレッドがそれを実行しているためです。割り込みはスレッド状態です。これは、sleepメソッドが終了するだけです。
ubuntudroid
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.