当前位置: 首页 > 知识库问答 >
问题:

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

汪凌
2023-03-14

让我们假设我们有这样一个用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,此时我们正在发送项信号。

发生的情况是执行立即终止。

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

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();
            }
        });
    }
}

所以,我的问题是——有没有可能不中断当前的执行,而是在一个单独的线程中处理< code>TERM信号(?)以便我能够设置< code>shutdown_flag = True以便< code>main中的循环有机会正常停止?

共有2个答案

卢阳成
2023-03-14

您可以使用SignalHandler。请查看此示例:https://dumpz.org/2707213/

它将赶上INTERRUPTED信号并取消设置操作标志,这反过来将允许应用程序优雅地关闭。

詹钊
2023-03-14

我重写了<code>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);
            }

        }
    });  
}
 类似资料:
  • 让我们假设我们有这样一个用python编写的琐碎守护进程: 我们使用< code>start-stop-daemon对其进行守护,默认情况下,它会在< code> - stop上发送< code > SIGTERM (< code > TERM )信号。 假设当前执行的步骤是。此时我们正在发送信号。 发生的情况是执行立即终止。 我发现我可以使用<code>signal.signal(signal.

  • 问题内容: 假设我们有一个用python编写的琐碎守护程序: 我们将它守护起来,默认使用它发送信号–。 假设当前执行的步骤是。此时此刻,我们正在发送TERM信号。 发生的情况是执行立即终止。 我发现我可以使用处理信号事件,但事实是它仍然会中断当前执行并将控制权传递给。 因此,我的问题是-是否可以不中断当前执行,而是TERM在单独的线程(?)中处理信号,以便能够进行设置,从而有机会优雅地停止运行?

  • 问题内容: 通过 设计, 人们只能将访问权限限制为仅通过身份验证的用户。 无论如何,当 未经 身份 验证的 用户尝试访问受限页面时,devise会自动导致重定向到 登录 页面。 因此,尝试打开http:// localhost:3000 / users / edit 将导致重定向到http:// localhost:3000 / users / sign_in 。 现在,如果我将链接http://

  • 问题内容: Java中有没有办法处理收到的SIGTERM? 问题答案: 是的,您可以向注册一个关闭挂钩。

  • 我最近在我的Spring4/Hibernate Web应用程序中实现了Spring Security来处理登录/退出和不同的用户角色。 经过大量阅读,它现在似乎工作得很好,但我注意到,由于错误的Spring Security配置而引发的异常没有使用我的自定义处理程序进行优雅的处理,而是显示为一个丑陋的Tomcat错误页面(显示HTTP状态500-UserDetailsService是必需的,后跟一

  • 假设我们有一个由唯一的s标识的对象集合,以及一个定义其层次结构的类。该类使用从节点(由它们的ID表示)到它们各自子ID的s来实现。 我想启用节点的子代流。一个简单的解决方案是: 在继续之前,我想对这个解决方案做以下断言。(我说的对吗?) > 从返回的会消耗资源(时间和内存)-相对于树的大小-与递归手工编码的复杂性顺序相同。特别是,代表迭代状态的中间对象(s,s,...)形成了一个堆栈,因此在任何给