Java 进程的退出机制与Shutdown hook

基本概念

进程与线程:一个进程包含多个线程,一个进程中所有线程都退出后,该进程才会退出。

用户线程与守护线程:任一用户线程未退出,JVM进程不退出,当所有用户线程都退出时,
守护线程线程自动退出。

Shutdown hook:进程退出时执行的钩子,主要用来清理释放资源使进程友好的退出。为了避免强制退出JVM可能产生的各种问题,我们可以采用Shutdownhook、发出信号的方式,主动的通知JVM退出,并在JVM关闭前,执行应用程序的一些扫尾工作,进一步保证应用程序可以安全的退出。

Linux下与结束进程相关的信号量

名称编号功能
SIGINT2中断(同 Ctrl + C)会触发触发shutdownhook
SIGKILL9终止进程,强制杀死进程
SIGTERM15终止进程,会先释放自己的资源,触发shutdownhook然后终止进程

Shutdown hook例子

    public class TestShutdownHook {

      public static void main(final String[] args) throws InterruptedException {
        Runtime.getRuntime().addShutdownHook(new Thread() {
          @Override
          public void run() {
            System.out.println("Shutdown hook ran!");
          }
        });
        while (true) {
          Thread.sleep(1000);
        }
      }
    }

在linux环境下执行如上述代码,当通过kill -15 pid,kill -2 pid结束该Java进程时ShutdownHook会被调用。但Kill -9 pid不会触发ShutdownHook调用。当通过kill -9去结束一个Java进程时,则需要通过另一个程序来判断进程是否被关闭。例如通过shell脚本。

#!/bin/bash java TestShutdownHook wait # notify your other app that you quit echo "TestShutdownHook quit"

不友好的shutdown hook

shutdown hook内部陷入死循环,或被block住,会使进程无法退出。

public class Main {

  public static void main(String[] args) throws Throwable {
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
      while (true) {
        try {
          TimeUnit.SECONDS.sleep(1);
          System.out.println("shutdown");
        }catch (Exception e) {

        }
      }
    }));
  }
}

这种情况结合外部程序或脚本可以先发出kill -15,kill -2 如果一段时间内检测到进程未关闭,那么再发出kill -9来结束进程。

参考

https://stackoverflow.com/questions/2541597/how-to-gracefully-handle-the-sigkill-signal-in-java?noredirect=1&lq=1

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值