First, I should point out that stopping a thread is NOT easy. In fact, in the general case, threads cannot be stopped safely:
You can call Thread.interrupt()
on a thread the you want to stop, but there is no guarantee that the thread will notice the interrupt, let alone actually stop.
You can call the deprecated Thread.stop()
method, but this method is unsafe. If you call it at an unfortunate moment, you can leave data structures in a half-updated state, leave other threads waiting (for ever) on signals that won't arrive and so on.
Here's how I'd implement a watchdog for method execution.
First I'd modify the method to add two calls to the watchdog service; e.g.
public void someMethod(...) {
Watchdog.startMethod(maxTime);
// do stuff
Watchdog.endMethod();
}
Next, I'd implement the Watchdog with a priority queue ordered on expiry time:
- The
startMethod(maxTime)
would add an entry to the queue with expiry time of now + maxTime
. The entry would include a reference to the current thread (when the method was called.
- The
endMethod()
would look for a (the) queue entry for the current thread, and remove it if found.
- The watchdog thread would periodically look at the first queue entry. If that entry had an expiry less than 'now', the watchdog would remove the entry, stop its thread and check the next entry. Repeat until the next entry hasn't expired.
Some thought would need to be given to the data structures, and to dealing with cases where endMethod
calls get skipped. (Indeed, since a method call can terminate due to an exception, the endMethod()
call really needs to be done in a finally
block.)
Note that the startMethod
and endMethod
calls could (and maybe should) be inserted by an annotation processor or something like that.
Given the complexity, and the fact that you can't guarantee to stop the thread (safely), I'd think of some solution that doesn't involve a method watchdog.