jvm安全退出

很多时候我们需要在退出的时候能够保证内存中的数据得到处理,比如在写文件的时候程序要退出,此时如果直接退出的话会造成部分数据还没有持久化到文件中,从而造成数据丢失。为了解决这个问题,我们需要在程序退出的时候能够捕获到该消息,然后做一些数据清理操作,目前有两种方案:

一种是采用SignalHandler类来进行相应的处理

另外一种是在JVM里注册一个“关闭钩子”(shutdown hook)

1、关于第一种方法,我们来看一个例子,代码如下:

/**
 * 信号注册及捕捉处理类
 * @author xiaoxiao
 */
@Component
public class SignalHelper implements SignalHandler {

	private Log log = LogFactory.getLog(getClass());
	
	@PostConstruct
	public void registSignal() {
        //注意这里并不是什么消息都能捕获,像kill -9或者断电等退出操作就捕获不了,所以尽量少用kill -9
		Signal.handle(new Signal("TERM"), this); //kill -15
		Signal.handle(new Signal("INT"), this); //CRTL+C
		log.info("注册信号成功");
	}
	
	@Override
	public void handle(Signal signal) { //捕捉信号,使程序优雅地退出
		log.info("捕捉到信号:" + signal.getName());
		new CleanerTask().run();
		System.exit(0); //捕捉到终止信号若不调用exit方法,则程序不会退出
	}
}

其中CleanerTask就是一个线程类,它里面会进行相应的数据清理操作,这个根据具体业务做相应操作,在程序启动的时候务必要执行registSignal函数,如果有退出信号,例如kill -15,此时就会执行handle函数。

2、关于第二种方法,注册"关闭钩子",代码如下:

AbstractApplicationContext ctx;
// 加载spring配置文件
ctx = new FileSystemXmlApplicationContext("mybean.xml");
//为了在非web环境下让spring容器优雅的关闭
ctx.registerShutdownHook();
ctx.start();

这里之所以用钩子,主要是用来在程序退出的时候将IOC容器资源释放掉,像web程序中自动会进行IOC容器资源释放,所以不需要我们做任何释放操作,但是在非web程序中,就不会自动释放spring中的IOC容器资源,所以需要我们手动进行释放资源。

当然我们也可以实现自己的关闭钩子(关闭钩子可以有多个),示例代码如下:

public class JVMHook {

 public static void start(){
  System.out.println("The JVM is started");
  Runtime.getRuntime().addShutdownHook(new Thread(){
   public void run(){
    try{
     //do something
     System.out.println("The JVM Hook is execute");
    }catch (Exception e) {
     e.printStackTrace();
    }
   }
  });
 }
 
 public static void main(String[] args) {
  start();
  System.out.println("The Application is doing something");  
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}

执行结果为:

The JVM is started
The Application is doing something
The JVM Hook is execute

参考文章:

文章1

文章2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值