Signals in Java
Here’s the translation of the Go code example to Java, with explanations in Markdown format suitable for Hugo:
Sometimes we’d like our Java programs to intelligently handle Unix signals. For example, we might want a server to gracefully shutdown when it receives a SIGTERM
, or a command-line tool to stop processing input if it receives a SIGINT
. Here’s how to handle signals in Java with threads.
import java.util.concurrent.CountDownLatch;
import sun.misc.Signal;
import sun.misc.SignalHandler;
public class SignalHandling {
public static void main(String[] args) {
// Java signal handling works by registering SignalHandler
// implementations for specific signals.
CountDownLatch sigReceived = new CountDownLatch(1);
// Register handlers for SIGINT and SIGTERM
SignalHandler handler = signal -> {
System.out.println();
System.out.println(signal.getName());
sigReceived.countDown();
};
Signal.handle(new Signal("INT"), handler);
Signal.handle(new Signal("TERM"), handler);
// This demonstrates a more realistic scenario of graceful shutdown.
Thread signalWaiter = new Thread(() -> {
try {
sigReceived.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
signalWaiter.start();
// The program will wait here until it gets the
// expected signal (as indicated by the CountDownLatch
// being decremented) and then exit.
System.out.println("awaiting signal");
try {
signalWaiter.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("exiting");
}
}
When we run this program it will block waiting for a signal. By typing ctrl-C
(which the terminal shows as ^C
) we can send a SIGINT
signal, causing the program to print INT
and then exit.
$ java SignalHandling
awaiting signal
^C
INT
exiting
Note: The sun.misc.Signal
and sun.misc.SignalHandler
classes are part of Sun’s proprietary API and may not be available in all Java implementations. For a more portable solution, consider using a third-party library like jnr-posix for signal handling.