正确地关闭Java进程

2019-04-22  本文已影响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主进程中开了一个子进程。正常来说,当主进程结束的时候,应该同时关闭这些子进程。

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

我选择第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. 什么是正常结束?

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

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

image.png

参考:

上一篇下一篇

猜你喜欢

热点阅读