今天看sofajraft源码看到了Java.Runtime.addShutdownHook(Thread hook)在这里整理了下相关内容。嗯,今天又学到了一点点[加油]
很多公司规范中都有规定不允许使用kill -9命令,这是为什么呢?
linux kill命令
开发或多或少都用过这个命令去杀时服务器上的进程。
- 命令的格式 kill[参数][进程号]
作用是向进程发送一个信号,默认是终止信号。
- 参数
-l 信号,若果不加信号的编号参数,则使用“-l”参数会列出全部的信号名称
-a 当处理当前进程时,不限制命令名和进程号的对应关系
-p 指定kill 命令只打印相关进程的进程号,而不发送任何信号
-s 指定发送信号
-u 指定用户
通常使用-l(信号)比较多,就比如说kill -9。
- 常用信号
HUP 1 类似于重启
INT 2 中断(同 Ctrl + C)
QUIT 3 退出(同 Ctrl + \\)
TERM 15 终止 (没有指定信号时默认15)
KILL 9 强制终止,不可捕获
CONT 18 继续(与STOP相反, fg/bg命令)
TSTP 20 暂停(同 Ctrl + Z)
STOP 19 功能和20类似,但是和9一样不可捕获
- kill -9 和 kill -15 的区别
kill -9要求接收到该信号的程序应该立即结束运行,不能被阻塞或者忽略。
kill -15应用程序有自主决定权:
1、立即停止程序
2、释放响应资源后停止程序
3、忽略该信号,继续执行程序??
因为有可能会忽略,因此kill -15是有可能无法终止进程的。
java shutdaown hulk
在Linux中,Java应用是作为一个独立进程运行的,Java程序的终止运行是基于JVM的关闭实现的,JVM关闭方式分为3种:
- 正常关闭:当最后一个非守护线程结束或者调用了System.exit或者通过其他特定平台的方法关闭(接收到SIGINT(2)、SIGTERM(15)信号等)
- 强制关闭:通过调用Runtime.halt方法或者是在操作系统中强制kill(接收到SIGKILL(9)信号)
- 异常关闭:运行中遇到RuntimeException异常等。
JDK提供了Java.Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子,在正常退出或异常退出时做一些额外的操作,比如清理内存之类的。大量开源中间件都使用了这个功能来进行优雅关闭,而这个钩子不能响应强制退出(比如kill -9)。
注意事项:
- 1.hook线程会延迟JVM的关闭时间,所以尽可能减少执行时间。
- 2.关闭钩子中不要调用system.exit(),会卡主JVM的关闭过程。但是可以调用Runtime.halt()
- 3.不能再钩子中进行钩子的添加和删除,会抛IllegalStateException
- 4.在system.exit()后添加的钩子无效,因为此时jvm已经关闭了。
- 5.当JVM收到SIGTERM命令(比如操作系统在关闭时)后,如果钩子线程在一定时间没有完成,那么Hook线程可能在执行过程中被终止。
- 6.Hook线程也会抛错,若未捕获,则钩子的执行序列会被停止。