在线上Java程序中经常遇到进程程挂掉,一些状态没有正确的保存下来,这时候就需要在JVM关掉的时候执行一些清理现场的代码。Java中得ShutdownHook提供了比较好的方案。
  JDK在1.3之后提供了Java Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子,这个钩子可以在以下几种场景被调用:

  • 1)程序正常退出
  • 2)使用System.exit()
  • 3)终端使用Ctrl+C触发的中断
  • 4)系统关闭
  • 5)使用Kill pid命令干掉进程

注:在使用kill -9 pid是不会JVM注册的钩子不会被调用。
在JDK中方法的声明:
public void addShutdownHook(Thread hook)
参数
hook -- 一个初始化但尚未启动的线程对象,注册到JVM钩子的运行代码。
异常
IllegalArgumentException -- 如果指定的钩已被注册,或如果它可以判定钩已经运行或已被运行
IllegalStateException -- 如果虚拟机已经是在关闭的过程中
SecurityException -- 如果存在安全管理器并且它拒绝的RuntimePermission(“shutdownHooks”)

代码示例:
使用Timer模拟一个工作线程,该线程重复工作十次,使用System.exit()退出,在清理现场代码CleanWorkThread 中,取消timer运行,并输出必要的日志信息。

package com.netease.test.java.lang;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger; /**
* Date: 14-6-18
* Time: 11:01
* 测试ShutdownHook
*/
public class TestShutdownHook { //简单模拟干活的
static Timer timer = new Timer("job-timer"); //计数干活次数
static AtomicInteger count = new AtomicInteger(0); /**
* hook线程
*/
static class CleanWorkThread extends Thread{
@Override
public void run() {
System.out.println("clean some work.");
timer.cancel();
try {
Thread.sleep(2 * 1000);//sleep 2s
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
//将hook线程添加到运行时环境中去
Runtime.getRuntime().addShutdownHook(new CleanWorkThread());
System.out.println("main class start ..... ");
//简单模拟
timer.schedule(new TimerTask() {
@Override
public void run() {
count.getAndIncrement();
System.out.println("doing job " + count);
if (count.get() == 10) { //干了10次退出
System.exit(0);
}
}
}, 0, 2 * 1000); }
}

运行后,可以模拟以上五种场景进行测试,只有kill -9 pid不会执行Hook里面的代码。

Java应用中使用ShutdownHook友好地清理现场的更多相关文章

  1. Java应用中使用ShutdownHook友好地清理现场(转)

    在线上Java程序中经常遇到进程程挂掉,一些状态没有正确的保存下来,这时候就需要在JVM关掉的时候执行一些清理现场的代码.Java中得ShutdownHook提供了比较好的方案. JDK在1.3之后提 ...

  2. Java应用中使用ShutdownHook友好地清理现场、退出JVM的2种方法

    Runtime.getRuntime().addShutdownHook(shutdownHook);    这个方法的含义说明:        这个方法的意思就是在jvm中增加一个关闭的钩子,当jv ...

  3. Java 7 中 NIO.2 的使用——第四节 文件和目录

    Files类提供了很多方法用于检查在于你真正实际去操作一个文件或目录.这些方法强烈推荐,也非常有用,也能避免很多异常的发生.例如,一个很好的习惯就是在你试着移动一个文件从一个地方到另一个地方的时候,先 ...

  4. Java 17 将要发布,补一下 Java 13 中的新功能

    本文章属于Java 新特性教程 系列,已经收录在 Github.com/niumoo/JavaNotes ,点个赞,不迷路. 自从 Oracle 调整了 Java 的版本发布节奏之后,Java 版本发 ...

  5. Java编程中“为了性能”尽量要做到的一些地方

    最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了. 下面是参考网络资源总结的一些在Ja ...

  6. 你的java 代码对JIT编译友好吗?

    JIT编译器是Java虚拟机(以下简称JVM)中效率最高并且最重要的组成部分之一.但是很多的程序并没有充分利用JIT的高性能优化能力,很多开发者甚至也并不清楚他们的程序有效利用JIT的程度. 在本文中 ...

  7. Java开发中常见的危险信号(中)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  8. 你的Java代码对JIT编译友好么?(转)

    JIT编译器是Java虚拟机(以下简称JVM)中效率最高并且最重要的组成部分之一.但是很多的程序并没有充分利用JIT的高性能优化能力,很多开发者甚至也并不清楚他们的程序有效利用JIT的程度. 在本文中 ...

  9. 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)

    编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...

随机推荐

  1. python类与对象的组合与继承

    1.把类的对象实例化放到一个新的类里面叫做类的组合,组合就是指几个横向关系的类放在一起,纵向关系的类放在一起是继承,根据实际应用场景确定.简单的说,组合用于“有一个”的场景中,继承用于“是一个”的场景 ...

  2. CF100015C

    主要找到环上任意一条边,有比较dis(u,v),dis(u,a)+w+dis(b,v),dis(u,b)+w+dis(a,u) 然后,然后没了 lca求dis(u,v):dis(u,v)=dis[u] ...

  3. 企业服务总线ESB

    # 企业服务总线ESB 由中间件技术实现并支持SOA的一组基础架构,支持异构环境中的服务.消息以及基于事件的交互,并且具有适当的服务级别和可管理性. 通过使用ESB,可以在几乎不更改代码的情况下,以一 ...

  4. Hyperledger Fabric Ledger——账本总账

    Ledger Ledger(账本)即所有的state transitions(状态切换),是有序且不可篡改的.state transitions(状态切换)是由参与方提交的chaincode(智能合约 ...

  5. Next Generation MSP 和传统MSP的区别

    1. 速度 -- 基础架构代码化快速部署 由于物理硬件已经在云上启动并运行,因此配置服务器要快得多.配置完成后,只有当MSP采用DevOps并将环境“基础设施作为代码”时,配置才能快速.云MSP可以轻 ...

  6. bootstrape3 模态

    version 2 的模态 不能在 version 3 上面用. http://schy-hqh.iteye.com/blog/1995690

  7. Scrum Meeting 13 -2014.11.19

    最近数据库和编译的实验课也开始了,大家晚上的时间直接被砍掉了大部分. 希望大家能顺利完成项目吧.剩下时间也不多了,如果程序还存在一些特别的问题和需要优化修改的地方也应该考虑留到下阶段进行了. Memb ...

  8. Daily Scrumming* 2015.11.1(Day 13)

    一.今明两天任务表 Member Today’s Task Tomorrow’s Task 江昊 实现API小的更改 实现前后端整合 杨墨犁 实现首页 修改首页 付帅 实现创建编辑登录登出 测试修改 ...

  9. MathExam任务一

    小学一二年级数学计算题 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 60 35 • Es ...

  10. java equals()方法的注意事项

    1.在写代码的时候,我们有时候需要判断两个相同类的对象的值是否全部相等,很多人想到的就是equals()方法,但是equals方法真的是可以比较吗?其实equals方法比较的并不是两个对象的值,它只是 ...