美文网首页
正确地关闭Java进程

正确地关闭Java进程

作者: 猫尾草 | 来源:发表于2019-04-22 15:10 被阅读0次

    1. 应用场景举例

    有一个视频处理的java工程,需要调用ffmpeg的转码方法(不要问为什么不用python,用python我还写啥;不要问为什么不用javacv,我就是想自己尝试一下java调用命令行),如下:

    Runtime.getRuntime().exec("ffmpeg -i test.mp4 -c copy -bsf:v h264_mp4toannexb -hls_time 3 enctest.m3u8");
    

    这就是在java主进程中开了一个子进程。正常来说,当主进程结束的时候,应该同时关闭这些子进程。

    • 1)关闭了主进程的时候子进程并不会自动关闭
    • 2)如果不及时关闭子进程,大量子进程严重占用资源

    为了关闭这些子进程,我们有两种选择来:

    • 1)查看系统进程,手动(或脚本)杀死所有由这个主进程打开的子进程;
    • 2)在主进程关闭的时候,采取一些方法关闭子进程

    我选择第2种方法。
    我们知道javabean有@PreDestroy方法用来在对象销毁之前执行一些操作,很容易想到进程应该也有类似的方法。这就是

     Runtime.getRuntime().addShutdownHook("进程关闭之前执行的方法");
    

    我们称这个东西为“关闭钩子”。在主进程正常结束(什么是正常结束?往下看)的时候,这个关闭钩子就会在进程结束前执行一次。
    给一个例子:

    public class HookTest {
        private static final void shutdownCallback() {
            System.out.println("Shutdown callback is invoked");
        }
        public static void main(String[] args) throws InterruptedException {
            Runtime.getRuntime().addShutdownHook(new Thread(() -> shutdownCallback())); // 这里用了java的新特性lambda,其实就是开一个线程
            Thread.sleep(10000);
        }
    }
    

    这个例子,正常结束(这里又提到了正常结束,往下看),就会输出:

    Shutdown callback is invoked.
    

    看到这里,至少你应该明白了一件事,在这个“关闭钩子”里面,我们可以进行临时文件清理、子进程关闭、通知其他程序本程序即将关闭。。。。这些工作。这样一个java进程就能被正常关闭。
    标题“正确地关闭进程”里面“正确”的意思就是让进程正常关闭

    2. 什么是正常结束?

    正常结束就是程序运行到最后自然推出?
    不是。
    正常技术包含如下几项:

    • 1)System.exit()
    • 2)Ctrl+C
    • 3)OutOfMemoryError
    • 4)kill [pid] (kill -9这种直接结束进程的不是,kill -15可以)

    通常来说,我们记得2和4就行,分别对应的是jar包在shell中直接执行和后台执行的关闭方法。
    这时候你可能会有一个问题(也可能你早就知道了),在IDE中运行时,怎么办?我难道测试关闭钩子的时候还得打包去运行?(这也是一个好办法,我看有的大佬推荐调试程序就是用的jar包而不是IDE,别问我为什么,我不知道)有一个更简单的方法,使用IDE“运行”面板中的退出按钮,而不是停止按钮,以idea举例,停止按钮就是我们经常点的红色方块按钮,退出按钮是一个方框带一个红色箭头。如下:

    image.png

    参考:

    相关文章

      网友评论

          本文标题:正确地关闭Java进程

          本文链接:https://www.haomeiwen.com/subject/vtbvgqtx.html