The code I've inherited is a server that spawns many different types of daemon threads that receive and respond to requests as they come in. Obviously, this is dangerous and needs to be refactored away. As it is now if the main program is halted while one of the daemons is servicing a request the thread could be killed midway through the request and leaving something in an inconsistent state.
However, there are quite a few threads spread through different areas of the code. If I had to manually close every one of the threads when a shutdown is called, well it could be a bit of a pain to get logic flow perfect without missing some obscure daemon.
What I would like to do instead is to have a thread that is like a daemon thread, but I can mark or toggle some section of the thread as a critical section; which will complete the therad from being reaped until it completes. While the daemon is blocking and waiting for requests it behaves like a daemon thread, doesn't prevent the VM from closing, and will be stopped immediately if the VM is shutting down. However, while the thread is actively servicing a specific request (a fraction of the time the thread is active) the thread will not be killed until it completes and exits it’s critical section. Once the thread finishes it's critical section it then becomes eligible to be killed. Ideally when no more non-daemon threads are available the VM would start it’s shut down process immediately, even if some daemons are still doing critical work, by reaping any daemon not in a critical state and then wait for each remaining 'daemon' to exit it's critical point so it could be killed.
Is there an easy way to get this behavior just by instantiating a Thread class (possibly one I write) or setting a Boolean, rather than having to explicitly write each thread to properly handle interrupts to behave like this? I'm looking for a mostly idiot proof way so that if plugins, running in such a thread, are not written to handle interrupts perfectly the thread will still properly complete it's critical section and then exit when the VM is shutting down.
However, there are quite a few threads spread through different areas of the code. If I had to manually close every one of the threads when a shutdown is called, well it could be a bit of a pain to get logic flow perfect without missing some obscure daemon.
Unfortunately the best way to do this is as you imply. You should have a destroy()
method on the classes that fork threads so they can explicitly clean up after themselves. But this does require someone calling those destroy methods when the application is terminating.
What I would like to do instead is to have a thread that is like a daemon thread, but has a certain critical section where it cannot be killed until it completes (or maybe times out if it takes too long?).
There is nothing in the Java threads that allows this behavior. Either a thread is daemon or it is not and this is set before the thread starts.
Is there an easy way to get this behavior just by instantiating a class or setting a Boolean
I think you are on to something here. I would have a ThreadUtils
class with a volatile boolean shutdown
field.
public class ThreadUtils {
private static volatile boolean shutdown = false;
/** called by main when the application is shutting down */
public static void shutdown() {
shutdown = true;
}
/** used by the various non-daemon threads to test for shutdown */
public static boolean isShutdown() {
return shutdown;
}
}
You main program would set the shutdown flag to true and then all of your threads would need to check this boolean in their code:
// we can test for shutdown only at "appropriate" points in the thread
while (!ThreadUtils.isShutdown()) {
...
// we are not ready to be killed here
...
}
Something like this pattern, although a bit gross, sounds like it fulfills your requirement.