java - 如何在 Java 中优雅地处理 SIGTERM 信号?

标签 java process daemon sigterm start-stop-daemon

假设我们有一个用 java 编写的这样一个简单的守护进程:

public class Hellow {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        while(true) {
            // 1. do
            // 2. some
            // 3. important
            // 4. job
            // 5. sleep
        }

    }
}

我们使用 start-stop-daemon 对其进行守护进程,它默认在 --stop 上发送 SIGTERM (TERM) 信号

假设当前执行的步骤是#2。就在此时此刻,我们正在发送 TERM 信号。

发生的是执行立即终止。

我发现我可以使用 addShutdownHook() 处理信号事件,但问题是它仍然会中断当前执行并将控制权传递给处理程序:

public class Hellow {
    private static boolean shutdownFlag = false;
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        registerShutdownHook();

        try {
            doProcessing();
        } catch (InterruptedException ex) {
            System.out.println(ex);
        }
    }

    static private void doProcessing() throws InterruptedException {
        int i = 0;
        while(shutdownFlag == false) {
            i++;
            System.out.println("i:" + i);
            if(i == 5) {
                System.out.println("i is 5");
                System.exit(1); // for testing
            }

            System.out.println("Hello"); // It doesn't print after System.exit(1);

            Thread.sleep(1000);
        }
    }

    static public void setShutdownProcess() {
        shutdownFlag = true;
    }

    private static void registerShutdownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                System.out.println("Tralala");
                Hellow.setShutdownProcess();
            }
        });
    }
}

所以,我的问题是 - 是否可以不中断当前执行,而是在单独的线程(?)中处理 TERM 信号,以便我能够设置 shutdown_flag = True 以便 main 中的循环有机会优雅地停止?

最佳答案

我重写了 registerShutdownHook() 方法,现在它可以正常工作了。

private static void registerShutdownHook() {
    final Thread mainThread = Thread.currentThread();
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            try {
                System.out.println("Tralala");
                Hellow.setShutdownProcess();
                mainThread.join();
            } catch (InterruptedException ex) {
                System.out.println(ex);
            }

        }
    });  
}

关于java - 如何在 Java 中优雅地处理 SIGTERM 信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47365753/

相关文章:

c++ - 获取流程描述

python - 需要让我的 python web 应用程序像守护进程一样 self 监控(保持事件状态)

java - 使用 SparkConf 连接到远程 Cassandra 集群时如何获得 pass "requires authentication"?

java - 您将如何编写自己的 Java 类以从 JFC 和 WFC 类继承?

c - 如何干净地重新开发系统功能 "system()"?

c# - 如何在 Windows/C# 上获取进程名称和顶部窗口的标题

php - 从 php 启动一个独立进程(通过 httpd)

作为 Unix 服务运行的 Java

java - 将图像插入 JTextPane 错误

java - 如何将使用 JFileChooser 拍摄的图像图标放在标签上?