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.