2009-04-26 20 views
5

ho il seguente codice in un Runnable che viene passato a un filo t:filo java che chiude presto e sospettosamente

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

ho colpito un bug in cui vedo situazione di stallo con le seguenti condizioni

  • solo l'inizio del messaggio di thread è stato stampato da miei log
  • Un dump filo mostra che la t filo (dovrebbe essere l'esecuzione di questo) non è più in esecuzione

Esiste un modo magico in cui questo thread potrebbe essere terminato in anticipo senza registrare un messaggio di fine thread o generare un'eccezione?

risposta

7

Sei sicuro che doStuff() non ha lanciato un Error? Cambia catch (Exception e) a catch (Throwable t). È possibile uccidere thread in Java con Thread.stop(), ma ciò è altamente improbabile.

+0

grazie mille. Il thread era OOMing - e dato che non stavo catturando il throwable (e forse altri logging erano mal configurati?), Non ho ricevuto alcuna notifica – Jacob

0

Certo, il thread potrebbe essere interrotto dopo la fine del blocco try/catch ma prima dell'ultima istruzione logger.debug. In tal caso, si genererebbe uno InterruptedException che, in linea di principio, potrebbe non essere registrato da nessuna parte (se il gestore di eccezioni predefinito è impostato per ignorare tali elementi).

Sembra uno scenario piuttosto improbabile, anche se ... è piuttosto difficile dire cosa succede senza sapere di più sul resto del programma.

+0

Presupposto I/O interrompibile sul registratore. –

1

Sei sicuro che dove si start() il filo, è anche uniscono() esso dopo?

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

A proposito, join() può lanciare un InterruptedException, quindi se qualcosa interrompe la discussione mentre è in esecuzione, uniscono vi informerà su questo lanciando questa eccezione.

Spero che questo aiuti.

1

Quando si cattura Exception, si cattura qualsiasi RunnableException e qualsiasi dichiarati gettati Exception, ma non si prenderà tutto ciò che si estende Error. Se vuoi veramente catturare qualsiasi cosa, allora devi prendere lo Throwable.

Se si vuole fare questo per soli fini di registrazione e non si cura perché le uscite della discussione, si può fare questo:

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

e la dichiarazione finally è garantito per eseguire a meno che il thread viene arrestato o deadlock o in qualche altro modo si ferma l'esecuzione senza un'eccezione.

Nella maggior parte dei miei programmi, installo uno UncaughtExceptionHandler in modo che possa conoscere ogni Thread che muore in modo imprevisto. È stato di grande aiuto nel tracciare i fallimenti. Questo è stato aggiunto al linguaggio di Java 5.

0

Ogni volta che intrappoli un'eccezione generale, ti suggerisco di registrarlo in modo da sapere qual è l'eccezione e che causa. Non riuscire a farlo non ti aiuterà affatto.