Update on getting the exit status of a thread

This always winds up happening to me- I think I’ve found some clever way of doing things, and then about twenty minutes after I write about it, I discover a much better, much simpler alternative.

In the case of the previous post, I wanted to get the exit status of a thread- i.e. did it exit normally, or did it fail with an error? I wanted to know specifically so that I could restart it. Annoyingly, and conveniently, there is a much easier way of doing that using the SingleThreadScheduledExecutor(ThreadFactory) method in the ScheduledExecutorService class. You provide it with a Thread Factory that’s configured to create your process you don’t want to die, and this function will execute the process as scheduled, spawning a new thread from the ThreadFactory if the command exits with an exception.

scheduler = Executors.newSingleThreadScheduledExecutor(myThreadFactory);

ScheduledFuture<?> schedule = scheduler.scheduleAtFixedRate(new Runnable(), 0, 2, TimeUnit.WEEKS);

Bam. Two lines of code. As long as you don’t cancel it, your process will be running every two weeks. We can even query the exit status like the last post if we really want to know the post-mortem on our schedule object, but there’s not a lot of point to that.

Getting the exit status of a thread in Java

Let’s say you have a thread that’s happily chugging along at a task- for example, parsing over 10,000 Wikipedia articles and corresponding medical databases for some heavy-duty automated updating. You’d like to have it so that if the task fails (which is more likely than not) the parent thread will just respawn it, but only if the thread terminated with an exception- i.e., did not exit normally. If it exited normally, well, great, no need to respawn it.

Ordinarily when you spawn threads they implement the Runnable interface, which does not have a return value. You can check if the thread is still alive, of course, and take action if it’s not- but this doesn’t tell you anything about how the thread terminated. You could use the Callable interface, which is basically identical to Runnable, except that you can return a result (maybe like those old-style Unix exit numbers, for instance), but many convenient methods in Java.Util.Concurrent only take Runnable-implementing threads (such as the ScheduledExecutorService.scheduleAtFixedRate method).

A way to have a runnable method basically give you some clue to its exit status is by querying the ScheduledFuture object you get by executing the scheduleAtFixedRate method:

ScheduledExecutorService scheduler = 
      Executors.newScheduledThreadPool(1);
ScheduledFuture<?> schedule = 
      scheduler.scheduleAtFixedRate(new RunnableObject(), 
                                      0, 2, TimeUnit.SECONDS);
try {
  Thread.sleep(10000)
  schedule.cancel(true);
  schedule.get();   // blocks; throws exceptions if the 
                    // current thread is finished.
} catch (CancellationException e) {
  // the thread was cancelled
} catch (ExecutionException e) {
  // the thread died from an exception- now we know!
} catch (InterruptedException e) {
  // the thread was interrupted
}

In the block where we see it died from an exception, we can add logic to restart it, if we want (which I do).

Anyway, as always, I’m sure there’s a 100 better ways to do this, but this seemed clean and easy. I enjoy using thrown exceptions for more than just printing stacktraces.