2016-06-02 11 views
1

Ich versuche mein erstes multi-threaded Programm in Java zu schreiben. Ich kann nicht verstehen, warum wir diese Ausnahmebehandlung um die for-Schleifen benötigen. Wenn ich ohne die try/catch-Klauseln kompiliere gibt es eine InterruptedException. (Hier ist die Botschaft:Warum muss ich jeden Thread.sleep() - Aufruf in eine try/catch-Anweisung umbrechen?

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
Unhandled exception type InterruptedException 

)

Aber wenn sie mit der try/catch laufen, die SYSOUT in den Fangblöcke werden nie angezeigt - keine solche Ausnahme impliziert ohnehin war gefangen!

public class SecondThread implements Runnable{ 
    Thread t; 

    SecondThread(){ 
     t = new Thread(this, "Thread 2"); 
     t.start(); 
    } 

    public void run(){ 
     try{ 
      for(int i=5 ; i>0 ; i--){ 
       System.out.println("thread 2: " + i); 
       Thread.sleep(1000); 
      } 
     } 
     catch(InterruptedException e){ 
      System.out.println("thread 2 interrupted"); 
     } 
    } 
} 


public class MainThread{ 

    public static void main(String[] args){ 
     new SecondThread(); 

     try{ 
      for(int i=5 ; i>0 ; i--){ 
       System.out.println("main thread: " + i); 
       Thread.sleep(2000); 
      } 
     } 
     catch(InterruptedException e){ 
      System.out.println("main thread interrupted"); 
     } 
    } 
} 
+3

'Wenn ich kompiliere ohne die try/catch-Klauseln gibt es eine InterruptedException': nein es nicht, es gibt einen Fehler, dass Sie diese checked Ausnahme nicht abfangen - das ist sehr unterschiedlich zu dem Compiler Ihnen eine Ausnahme zu geben. – OrangeDog

+0

Wenn ich kompilieren, sagt es so: Exception in thread "main" java.lang.Error: Ungelöste Kompilation Problem: \t Unbehandelte Ausnahme Typ InterruptedException \t bei MainThread.main (MainThread.java:10) –

+0

@SergioGliesh: bearbeite deine Frage, schreibe sie nicht in einen Kommentar. –

Antwort

5

Verfahren Thread.sleep InterruptedException wirft, wenn er sich außerhalb des Stromflusses zu den aktuellen Thread irgendwo seinen Interrupt-Flag gesetzt hat, Aufwachen aus dem Schlaf früh und so dass Sie die Ausnahme verwenden Steuerung zu verlagern feststellt, dass. Dieses Flag wird nur gesetzt, wenn etwas Interrupt auf dem Thread aufruft.

Da Ihr Programm Interrupt auf keinem der Threads aufruft, wird InterruptedException nicht ausgelöst, wenn Sie dieses Programm ausführen. Der Compiler erfordert weiterhin, dass Sie die Ausnahme abfangen, da es sich bei der sleep-Methode um eine geprüfte Ausnahme handelt.

Wenn Sie fügen Sie eine Methode wie folgt

SecondThread
public void cancel() { 
    t.interrupt(); 
} 

dann im Hauptverfahren abzubrechen nennen, wie folgt aus:

public static void main(String[] args){ 
    SecondThread secondThread = new SecondThread(); 

    try{ 
     for(int i=5 ; i>0 ; i--){ 
      System.out.println("main thread: " + i); 
      Thread.sleep(2000); 
      secondThread.cancel(); 
     } 
    } 
    catch(InterruptedException e){ 
     System.out.println("main thread interrupted"); 
    } 
} 

Sie die println sehen werden, wo die InterruptedException verfängt in SecondThreads Run-Methode.

Kompilierfehler werden in Eclipse auf der Registerkarte "Probleme" angezeigt. Sie werden nicht nur im Editor aufgerufen, sondern werden auch rot unterstrichen angezeigt, wenn Sie den Code bearbeiten. Wenn Sie dieses Programm ausführen, werden alle Ausnahmen zusammen mit der Programmausgabe in die Konsole geschrieben.

0

InterruptedException ist eine geprüfte Ausnahme und muss abgefangen werden. In Ihrem Code wird es von der Sleep-Methode geworfen. Wenn Sie es also nicht umbrechen oder erneut ausführen, wird der Compiler angehalten, da es sich um eine geprüfte Ausnahme handelt.

Aber in Ihrem Beispielprogramm wird es nie unter normalen Bedingungen geworfen werden, da Sie nicht unterbrechen. Es ist jedoch da, um sicherzustellen, dass es einen Bearbeitungscode gibt, wenn ein Thread, der schläft, wartet oder anderweitig in einem "Zombie" -Status ist, ein Interrupt-Flag gesetzt hat und somit entweder nach Code oder nach Betriebssystemebene unterbrochen wird Anruf.

So ist es in der Tat benötigt, um zu fangen, und es hat gültige Verwendungen.

0

When I compile without the try/catch clauses it gives an InterruptedException.

Ausnahmen werden zur Laufzeit geworfen, nicht während der Kompilierung, dies kann also nicht wahr sein!

Wahrscheinlich waren die Compiler-Fehler von Ihnen bekommen, dass Thread.sleepInterruptedException werfen kann, aber SecondThread.run, von der Thread.sleep genannt wird, erklärt nicht, dass sie es werfen können. Daher schlägt der Compiler fehl, da die Ausnahme nirgendwohin gehen kann.

Normalerweise gibt es zwei Möglichkeiten, dieses Problem zu lösen:

  • fangen die Ausnahme oder
  • fügen Sie eine throws Klausel zu Ihrer Methode.

Letzteres ist in diesem Fall nicht möglich, da SecondThread.run Überschreibungen von Runnable.run, die erklären nicht, dass es irgendeine Ausnahme auslöst. Sie müssen also die Ausnahme abfangen.

Wenn dies nicht der Fall ist, oder Sie meinten "Wenn Sie nach dem Kompilieren ohne die try/catch-Klauseln eine InterruptedException eingeben.", Geben Sie bitte die genaue Fehlermeldung an, die Sie erhalten haben. Eigentlich solltest du das immer tun, wenn du hier Fragen stellst.

+0

Ich weiß nicht einmal, wie man Kompilierungszeit gegen Laufzeitfehler in Eclipse identifiziert! Dies ist, was ist, sagt trotzdem: Exception in thread "main" java.lang.Error: Ungelöste Kompilation Problem: \t Unbehandelte Ausnahme Typ InterruptedException \t bei MainThread.main (MainThread.java:10) –

+0

Wenn es passiert, wenn Sie kompilieren: Es ist ein Fehler bei der Kompilierung. Wenn es passiert, wenn der Code ausgeführt wird: Es ist ein Laufzeitfehler. Hinweis: Wenn "Ungelöstes Kompilierungsproblem" angezeigt wird, handelt es sich um einen Kompilierungsfehler. –

0

Sie müssen in Ihren Threads mit InterruptedException umgehen, weil Sie Methoden aufrufen, die InterruptedException auslösen, und Java ist so konzipiert, dass Sie immer geprüfte Ausnahmen behandeln müssen. Das heißt, "in einem Thread" ist irrelevant.

Wie sagt es in JLS Sec 11.2:

The Java programming language requires that a program contains handlers for checked exceptions which can result from execution of a method or constructor (§8.4.6, §8.8.5).

Diese Handler in Form von try/catch (InterruptedException) sein kann, oder throws InterruptedException; Sie können Letzteres jedoch nicht verwenden, da die Methodensignatur void run() Ihnen nicht erlaubt, eine geprüfte Ausnahme hinzuzufügen.

Als solche müssen Sie versuchen/fangen.