如何在Java中正常处理SIGTERM信号? [英] How to process SIGTERM signal gracefully in Java?

查看:765
本文介绍了如何在Java中正常处理SIGTERM信号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有一个用Java编写的琐碎的守护程序:

Let's assume we have such a trivial daemon written in 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)信号

and we daemonize it using start-stop-daemon which by default sends SIGTERM (TERM) signal on --stop

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

Let's suppose the current step performed is #2. And at this very moment we're sending TERM signal.

发生的事情是执行立即终止.

What happens is that the execution terminates immediately.

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

I've found that I can handle the signal event using addShutdownHook() but the thing is that it still interrupts the current execution and passes the control to handler:

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中的循环有机会优雅地停下来吗?

So, my question is - is it possible to not interrupt the current execution but handle the TERM signal in a separated thread (?) so that I would able to set shutdown_flag = True so that loop in main would had a chance to stop gracefully?

推荐答案

我重写了registerShutdownHook()方法,现在它可以按我的意愿工作.

I rewritten the registerShutdownHook() method and now it works as I wanted.

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中正常处理SIGTERM信号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆