dimanche 21 février 2016

Prevent exiting the loop on runtime exception in Java

I have a service, and I would like it to have the following behavior:

  1. If service receives InterruptedException, or JVM shuts down, it should try to stop gracefully
  2. If there's some "catastrophic" event, the service should just quit
  3. Any other exception should be logged, state should reset, and loop should keep running
  4. Loop should not quit under any other circumstance.

So here's a overly simplified version of what I came up with.

On class level:

private static volatile boolean keepRunning = true;

static {
    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            keepRunning = false;
        }
    }); 
}

And then the loop:

while(keepRunning) {
    try {
        // Do something useful
        Thread.sleep(10000); // just an example of something that can cause InterruptedException 
    }
    catch(InterruptedException e) { 
        keepRunning = false;
    }
    catch(Exception e) { // catches all exceptions, but not any errors
        // log it
        // reset state
    }
}
if(!keepRunning) {
    // shut down gracefully
}

It seems satisfies all 4 conditions, but there are some problems and unclear parts:

  1. (problem) Catching Exception and not doing anything is against all good practices. But is it acceptable in this case, or there's a better solution?
  2. (question) Is not catching Error all I need to do to satisfy condition #2? Or are there other situations I should be aware of?
  3. (unclear) Usually it's recommended that the "shut down gracefully" code goes into finally section after exception, and I don't really like that I have to check it after loop (if(!keepRunning)). But it seems doesn't fit in finally in this case. Is there a better way to do that?
  4. (question) This code is written for Java 7. Would anything be changed/improved with Java 8?

I will appreciate either direct answers to my questions, or pointers to different patterns/solutions. Thanks in advance.

Aucun commentaire:

Enregistrer un commentaire