Question
How do you handle clean up when the program receives a kill signal?
For instance, there is an application I connect to that wants any third party app (my app) to send a finish command when logging out. What is the best say to send that finish command when my app has been destroyed with a kill -9?
How-To
The way to handle this for anything other than kill -9 would be to register a shutdown hook. If you can use (SIGTERM) kill -15 the shutdown hook will work. (SIGINT) kill -2 DOES cause the program to gracefully exit and run the shutdown hooks.
Regarding to registering a new virtual-machine shutdown hook, the Java virtual machine shuts down in response to two kinds of events:
* The program exits normally, when the last non-daemon thread exits or
* The virtual machine is terminated in response to a user
On a kill -15 it DOES run the shutdown hook every time with below sample code:
- package test;
- public class TestShutdownHook {
- public static void main(final String[] args) throws InterruptedException
- {
- Runtime.getRuntime().addShutdownHook(new Thread()
- {
- @Override
- public void run()
- {
- System.out.println("Shutdown hook ran!");
- }
- });
- while (true)
- {
- Thread.sleep(1000);
- }
- }
- }
By using the Sun internal sun.misc.Signal.handle(Signal, SignalHandler) method call you are also able to register a signal handler, but probably not for signals like INT or TERM as they are used by the JVM. To be able to handle any signal you would have to jump out of the JVM and into Operating System territory.
What I generally do to (for instance) detect abnormal termination is to launch my JVM inside a Perl script, but have the script wait for the JVM using thewaitpid system call. I am then informed whenever the JVM exits, and why it exited, and can take the necessary action.
Below are sample code to catch signal SIGHUP(1) and SIGABRT(6) by calling Signal.handle(Signal, SignalHandler):
- package test;
- import sun.misc.Signal;
- import sun.misc.SignalHandler;
- public class SignalTest {
- public static class TestSignalHandler implements SignalHandler
- {
- @Override
- public void handle(Signal sig) {
- System.out.printf("\t[Info] Handle Signal: %s(%d)\n", sig, sig.getNumber());
- }
- }
- public static void main(String args[]) throws Exception
- {
- TestSignalHandler handler = new TestSignalHandler();
- Signal.handle(new Signal("ABRT"), handler);
- Signal.handle(new Signal("HUP"), handler);
- while(true)
- {
- Thread.sleep(1000);
- }
- }
- }
Supplement
* Wiki - Unix Signal
* Java Code Examples for sun.misc.SignalHandler
* Oracle Document - Integrating Signal and Exception Handling
沒有留言:
張貼留言