Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java thread terminating early and suspiciously

I have the following code in a Runnable that gets passed to a thread t:

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

I've hit a bug where I see deadlock with the following conditions

  • only the start of thread message has been printed by my logs
  • A thread dump shows that the thread t (supposed to be executing this) is no longer running

Is there some magical way this thread could have terminated early without either logging an end of thread message OR throwing an exception?

like image 269
Jacob Avatar asked Apr 26 '09 23:04

Jacob


3 Answers

Are you sure that doStuff() did not throw an Error? Change catch (Exception e) to catch (Throwable t). It's possible to kill threads in Java with Thread.stop(), but that is highly unlikely.

like image 58
Esko Luontola Avatar answered Sep 21 '22 02:09

Esko Luontola


Are you sure that where you start() the Thread, you also join() it afterwards?

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() may throw an InterruptedException, so if something interrupts your thread while it's running, join will inform you about this by throwing this exception.

Hope this helps.

like image 22
ivan_ivanovich_ivanoff Avatar answered Sep 22 '22 02:09

ivan_ivanovich_ivanoff


When you catch Exception, you will catch any RunnableException and any declared thrown Exception, but you will not catch anything that extends Error. If you truly want to catch anything, then you need to catch Throwable.

If you want to do this for logging purposes only and you don't care why the Thread exits, you can do this:

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

and the finally statement is guaranteed to execute unless the Thread is stopped or deadlocks or in some other way stops executing without an Exception.

In most of my programs, I install an UncaughtExceptionHandler so that I'll know about every Thread that dies unexpectedly. It's been a tremendous help in tracking failures. This was added to the language as of Java 5.

like image 36
Eddie Avatar answered Sep 22 '22 02:09

Eddie