2009-04-26 7 views
5

beendet Ich habe den folgenden Code in einem Runnable, die zu einem Faden t übergeben werden:Java-Thread früh und verdächtig

public void run() { 
     logger.debug("Starting thread " + Thread.currentThread()); 

     try { 
      doStuff(); 
     } catch (Exception e) { 
     logger.debug("Exception in Thread " + Thread.currentThread()); 
     } 

     logger.debug("End of thread " + Thread.currentThread()); 
    } 

ich einen Fehler getroffen habe, wo ich Deadlock mit den folgenden Bedingungen siehe

  • nur der Anfang Thread Nachricht von meinen Protokoll gedruckt worden
  • Ein Thread-Dump zeigt, dass der Faden t (sollte das seine Ausführung) ist nicht mehr
  • läuft

Gibt es einen magischen Weg, wie dieser Thread vorzeitig beendet werden könnte, ohne eine Thread-Ende-Nachricht zu protokollieren ODER eine Ausnahme auszulösen?

Antwort

7

Sind Sie sicher, dass doStuff() keinen Error geworfen hat? Ändern Sie catch (Exception e) zu catch (Throwable t). Es ist möglich, Threads in Java mit Thread.stop() zu beenden, aber das ist sehr unwahrscheinlich.

+0

vielen Dank. Es stellte sich heraus, dass der Thread OOMing war - und da ich nicht würfeln konnte (und vielleicht wurde eine andere Protokollierung falsch konfiguriert?), Bekam ich keine Benachrichtigung – Jacob

0

Sicher, erhält das Gewinde könnte nach dem Ende des try/catch Blockes unterbrochen, aber vor der letzten logger.debug Aussage. In diesem Fall würde es eine InterruptedException werfen, die im Prinzip möglicherweise nirgendwo aufgezeichnet wird (wenn der Standardausnahmebehandler eingestellt ist, solche Dinge zu ignorieren).

Das scheint ein ziemlich unwahrscheinliches Szenario zu sein, obwohl ... es ist schwer zu sagen, was vor sich geht, ohne mehr über den Rest Ihres Programms zu wissen.

+0

Angenommen, unterbrechungsfreie E/A am Logger. –

1

Sind Sie sicher, dass dort, wo Sie () den Thread zu starten, Sie auch join() es danach?

Runnable myRunnable=new Runnable(){ 
    @Override 
    public void run(){ 
    // your original code goes here 
    } 
}; 

Thread myThread=new Thread(myRunnable); 

myThread.start(); 

myThread.join(); // magic happens here! it waits for the thread to finish ;) 

By the way, join() eine InterruptedException, werfen kann so, wenn etwas Thread unterbricht, während es läuft, beitreten werden Sie darüber informieren, indem diese Ausnahme zu werfen.

Hoffe, das hilft.

1

Wenn Sie Exception fangen, wird fangen Sie jede RunnableException und jede Exception geworfen erklärt, aber Sie werden nichts fangen, die Error erstreckt. Wenn Sie wirklich irgendeine Sache fangen wollen, dann müssen Sie Throwable fangen.

Wenn Sie nur das für die Anmeldung Zwecke tun möchten und Sie kümmern sich nicht, warum der Thread beendet, können Sie dies tun:

public void run() { 
    logger.debug("Starting thread " + Thread.currentThread()); 
    try { 
    // The work of your Thread 
    } finally { 
    logger.debug("End of thread " + Thread.currentThread()); 
    } 
} 

und die finally Anweisung garantiert auszuführen, es sei denn der Thread gestoppt wird oder Deadlocks oder auf andere Weise stoppt Ausführung ohne eine Ausnahme.

In den meisten meiner Programme installiere ich eine UncaughtExceptionHandler, so dass ich über jeden Thread weiß, der unerwartet stirbt. Es war eine enorme Hilfe bei der Verfolgung von Fehlern. Dies wurde der Sprache ab Java 5 hinzugefügt.

0

Immer wenn Sie eine allgemeine Ausnahme abfangen, schlage ich vor, dass Sie sie protokollieren, damit Sie wissen, was die Ausnahme war und es verursacht. Andernfalls wird Ihnen nichts helfen.