beeef
beeef

Reputation: 2702

Java - application doesn't work correctly after a thread crashes

I have a Java applcation which uses multiple threads which start after a given time using a ScheduledExecutorService. Every hour a thread starts, does some work and terminates correctly. But sometimes (e.g. when a HTTP Request doesn't work) this thread crashes and the executor service doesn't start such a thread any more. Then I have to exit the application (using Ctrl-C) and restart it again.

Is this possible that a crashing thread interrupts the ExecutorService to instantiate new Threads? I don't want to always check if the application is still running or not, because it's running on my Raspberry Pi and should run 24/7.

Maybe you can help me to find a solution for my problem!

EDIT:

The ExecutorService also runs on its own thread. This is how the threads are started:

@Override
public void run() {
    threadFuture = executorService.scheduleAtFixedRate(new IntervalThread(i, p, c, a), 60, 60, TimeUnit.MINUTES);
}

And this is the thread which gets called every 60 minutes:

@Override
public void run() {

    try {
        // do some HTTP request here
        // if an error occurs, catch it and log the error message
    } catch (Exception e) {
        LOGGER.error(e.getMessage());
    }
}

If the thread (which makes HTTP requests) chrashed, the whole ExecutorService isn't working any more. How can that be possible if I catch every exception?

Upvotes: 1

Views: 1111

Answers (1)

Anton Krosnev
Anton Krosnev

Reputation: 4132

Your case does have an explanation, since ScheduledThreadPoolExecutor

If any execution of the task encounters an exception, subsequent executions are suppressed.

Although you are executing the entire task/work in try{}catch(Exception) block, there are cases, where Throwable might "escape" the catch block:

  1. Some kind of Error (e.g. OutOfMemoryError) has occurred.

  2. Your logging code LOGGER.error(e.getMessage()); has thrown an exception, while logging.

I would recommend you the following modification to understand what is going on:

@Override
public void run() {
 try {
  try {
    // do some HTTP request here
    // if an error occurs, catch it and log the error message
  } catch (Exception e) {
     LOGGER.error(e.getMessage());
  }
 } catch (Throwable t){
    t.printStackTrace(); // this would require redirect output like java -jar my.jar >> error_log.txt
    // try clean up and exit jvm with System.exit(0);

}    

Upvotes: 2

Related Questions