Wann löst Japas Thread.sleep eine InterruptedException aus?

110

Wann löst Japas Thread.sleep eine InterruptedException aus? Ist es sicher, es zu ignorieren? Ich mache kein Multithreading. Ich möchte nur ein paar Sekunden warten, bevor ich eine Operation erneut versuche.

Manki
quelle
1
Kommt darauf an, in welchem ​​Sinne du "ignorieren" meinst. InterruptedExceptionAusnahme ist eine gefangen, so dass Sie nicht kompilieren können , wenn Sie diese Art von Ausnahme auf jeder Methode behandeln oder erklären , die einen beitritt oder schlafen Thread, oder Anrufe wait()auf Object.
8bitjunkie

Antworten:

41

Sie sollten die Ausnahme im Allgemeinen NICHT ignorieren. Schauen Sie sich das folgende Papier an:

Schlucken Sie keine Interrupts

Manchmal ist das Auslösen von InterruptedException keine Option, z. B. wenn eine von Runnable definierte Aufgabe eine unterbrechbare Methode aufruft. In diesem Fall können Sie InterruptedException nicht erneut auslösen, möchten aber auch nichts tun. Wenn eine Blockierungsmethode eine Unterbrechung erkennt und eine InterruptedException auslöst, wird der unterbrochene Status gelöscht. Wenn Sie InterruptedException abfangen, diese aber nicht erneut auslösen können, sollten Sie Beweise dafür aufbewahren, dass die Unterbrechung aufgetreten ist, damit Code weiter oben im Aufrufstapel von der Unterbrechung erfahren und darauf reagieren kann, wenn dies gewünscht wird. Diese Aufgabe wird ausgeführt, indem Sie interrupt () aufrufen, um den aktuellen Thread "erneut zu unterbrechen", wie in Listing 3 gezeigt. Wenn Sie InterruptedException abfangen und nicht erneut auslösen, unterbrechen Sie den aktuellen Thread zumindest erneut, bevor Sie zurückkehren.

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();
         }
    }
}

Das gesamte Papier finden Sie hier:

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

Benny Bottema
quelle
38

Wenn ein InterruptedExceptiongeworfen wird, bedeutet dies, dass etwas diesen Thread unterbrechen (normalerweise beenden) möchte. Dies wird durch einen Aufruf der Thread- interrupt()Methode ausgelöst . Die Wartemethode erkennt dies InterruptedExceptionund löst ein aus, damit der Catch-Code die Anforderung zur Beendigung sofort verarbeiten kann und nicht warten muss, bis die angegebene Zeit abgelaufen ist.

Wenn Sie es in einer Single-Thread-App (und auch in einigen Multi-Thread-Apps) verwenden, wird diese Ausnahme niemals ausgelöst. Das Ignorieren durch eine leere catch-Klausel würde ich nicht empfehlen. Das Werfen des InterruptedExceptionlöscht den unterbrochenen Zustand des Threads. Wenn dies nicht richtig gehandhabt wird, gehen diese Informationen verloren. Deshalb würde ich vorschlagen zu laufen:

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

Was diesen Zustand wieder setzt. Beenden Sie danach die Ausführung. Dies wäre korrektes Verhalten, auch wenn es nie hart angewendet wird.

Was besser sein könnte, ist Folgendes hinzuzufügen:

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

... Anweisung zum catch-Block. Das bedeutet im Grunde, dass es niemals passieren darf. Wenn der Code also in einer Umgebung wiederverwendet wird, in der er möglicherweise auftritt, wird er sich darüber beschweren.

Christian
quelle
5
Zusicherungen in Java sind standardmäßig deaktiviert . Also ist es besser, einfach einen zu werfen RuntimeException.
Evgeni Sergeev
11

Der Java Specialists Newsletter (den ich vorbehaltlos empfehlen kann) hatte einen interessanten Artikel darüber und wie man damit umgeht InterruptedException. Es lohnt sich zu lesen und zu verdauen.

Brian Agnew
quelle
1
Was sagt es?
theonlygusti
4

Methoden wie sleep()und wait()der Klasse Threadkönnten eine werfen InterruptedException. Dies wird passieren, wenn ein anderer threaddas threadWarten oder Schlafen unterbrechen wollte .

Benutzer7805041
quelle
3

Eine solide und einfache Möglichkeit, mit Single-Threaded-Code umzugehen, besteht darin, ihn abzufangen und in einer RuntimeException erneut zu speichern, um zu vermeiden, dass er für jede Methode deklariert werden muss.

Sternenblau
quelle
-7

Das InterruptedExceptionwird normalerweise geworfen, wenn ein Schlaf unterbrochen wird.

BrutalOst
quelle
13
Das ist falsch, da nicht der Schlaf selbst unterbrochen wird, sondern der Thread, der ihn ausführt. Unterbrochen ist ein Thread-Status. Es führt nur dazu, dass die Schlafmethode beendet wird.
Ubuntudroid