Java利用ShutDownHook关闭系统资源

Java关闭钩子

在Java程序中可以通过添加关闭钩子,实现在程序退出时关闭资源的功能。

使用Runtime.addShutdownHook(Thread hook)向JVM添加关闭钩子

    public void addShutdownHook(Thread hook) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("shutdownHooks"));
        }
        ApplicationShutdownHooks.add(hook);
    }

ShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子,这个钩子可以在以下几种场景被调用:

1)程序正常退出

2)使用System.exit()

3)终端使用Ctrl+C触发的中断

4)系统关闭

5)使用Kill pid命令干掉进程

在Eclipse中使用关闭钩子

在Eclipse中直接点击Terminate关闭程序时不会触发关闭钩子的。在Linux下使用kill -9也是不会触发钩子的

如果想在Eclipse中实现关闭钩子的功能,需要另起一个线程监听控制台,在控制台输入Enter时关闭系统

/**
 * <p>类描述: 输入Enter键关闭系统 </p>
 * <p>创建人:王成委  </p>
 * <p>创建时间:2015年6月8日 下午5:23:31  </p>
 */
public class ExitThread extends Thread {
    private Log logger = LogFactory.getLog(getClass());

    public void run() {
        logger.info("press ENTER to call System.exit(0) ");
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.exit(0);
    }

}

Spring中关闭资源的配置

在使用Spring时,可以在Bean中配置destroy-method来实现系统关闭时对Bean的一些处理。

    <bean id="simpleHandler" class="com.tiamaes.gjds.socket.server.SimpleHanlder" destroy-method="destroy">
        <property name="annotationSocketServiceFactory" ref="annotationSocketServiceFactory" />
    </bean>
    //此方法需要声明void,并且没有任何参数
    public void destroy(){
        logger.info("Stop socket handler.");
    }

Java+Spring实现在程序退出时关闭Spring

/**
 * <p>类描述: 系统关闭钩子,用于关闭Spring资源 </p>
 * <p>创建人:王成委  </p>
 * <p>创建时间:2015年6月8日 下午5:06:46  </p>
 */
public class ShutDownHook extends Thread {

    private Log logger = LogFactory.getLog(getClass());

    private ConfigurableApplicationContext applicationContext;

    public ShutDownHook(ConfigurableApplicationContext applicationContext ){
        super();
        this.applicationContext = applicationContext;
    }

    @Override
    public void run() {
        logger.info("Start clean the login info.");
        //在系统关闭时,清理所有用户的登录状态
        TbDxpUserLoginStatusRepository repository = applicationContext.getBean(TbDxpUserLoginStatusRepository.class);
        repository.deleteAll();
        applicationContext.close();
        logger.info("Socket server shutdown");
    }
}

在ShutdownHook实例化时需要传入Spring上下文,在系统关闭时调用ApplicationContext的Close方法。

    public static void main(String[] args) {
        ClassPathXmlApplicationContext ct =
                new ClassPathXmlApplicationContext("applicationContext.xml");

        Runtime.getRuntime().addShutdownHook(new ShutDownHook(ct));

        //在正式部署时不需要下面的代码,这段代码仅供调试时使用
        Thread thread = new ExitThread();
        thread.start();
    }

最终效果如下

2015-06-09 09:43:51,233 INFO ClassPathXmlApplicationContext  - Refreshing org.springframework.context.support.[email protected]2e52cdcc: startup date [Tue Jun 09 09:43:51 CST 2015]; root of context hierarchy
2015-06-09 09:43:52,263 INFO XmlBeanDefinitionReader  - Loading XML bean definitions from class path resource [applicationContext.xml]
2015-06-09 09:43:55,559 INFO XmlBeanDefinitionReader  - Loading XML bean definitions from class path resource [applicationContext-service.xml]
2015-06-09 09:43:55,724 INFO XmlBeanDefinitionReader  - Loading XML bean definitions from class path resource [applicationContext-db.xml]
2015-06-09 09:44:01,358 INFO PropertyPlaceholderConfigurer  - Loading properties file from class path resource [jdbc.properties]
2015-06-09 09:44:02,687 INFO MLog  - MLog clients using slf4j logging.
2015-06-09 09:44:06,563 INFO C3P0Registry  - Initializing c3p0-0.9.5-pre9 [built 08-October-2014 03:06:08 -0700; debug? true; trace: 10]
2015-06-09 09:44:08,930 INFO LocalContainerEntityManagerFactoryBean  - Building JPA container EntityManagerFactory for persistence unit ‘Oracle‘
2015-06-09 09:44:09,251 INFO LogHelper  - HHH000204: Processing PersistenceUnitInfo [
    name: Oracle
    ...]
2015-06-09 09:44:13,400 INFO Version  - HHH000412: Hibernate Core {4.3.7.Final}
2015-06-09 09:44:13,404 INFO Environment  - HHH000206: hibernate.properties not found
2015-06-09 09:44:13,439 INFO Environment  - HHH000021: Bytecode provider name : javassist
2015-06-09 09:44:15,016 INFO Version  - HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
2015-06-09 09:44:15,660 INFO Dialect  - HHH000400: Using dialect: org.hibernate.dialect.Oracle10gDialect
2015-06-09 09:44:15,739 INFO LobCreatorBuilder  - HHH000422: Disabling contextual LOB creation as connection was null
2015-06-09 09:44:16,056 INFO ASTQueryTranslatorFactory  - HHH000397: Using ASTQueryTranslatorFactory
2015-06-09 09:44:21,032 INFO EhCacheManagerFactoryBean  - Initializing EhCache CacheManager
2015-06-09 09:44:21,977 INFO ExitThread  - press ENTER to call System.exit(0) 

2015-06-09 09:54:23,694 INFO ShutDownHook  - Start clean the login info.
2015-06-09 09:54:23,787 INFO AbstractPoolBackedDataSource  - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, acquireRetryAttempts -> 0, acquireRetryDelay -> 1000, autoCommitOnClose -> true, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 5000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 1hge7dt991ndh1jygiycad|7402fff0, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> oracle.jdbc.OracleDriver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceUseNamedDriverClass -> false, identityToken -> 1hge7dt991ndh1jygiycad|7402fff0, idleConnectionTestPeriod -> 0, initialPoolSize -> 5, jdbcUrl -> jdbc:oracle:thin:@192.168.57.62:1521:orcl, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 36000, maxIdleTimeExcessConnections -> 1800, maxPoolSize -> 20, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 5, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
Hibernate: select tbdxpuserl0_.SESSION_ID as SESSION_ID1_1_, tbdxpuserl0_.CREATE_TIME as CREATE_TIME2_1_, tbdxpuserl0_.IP_ADDR as IP_ADDR3_1_, tbdxpuserl0_.LOGIN_TIME as LOGIN_TIME4_1_, tbdxpuserl0_.status as status5_1_, tbdxpuserl0_.USER_ID as USER_ID6_1_, tbdxpuserl0_.username as username7_1_ from TB_DXP_USER_LOGIN_STATUS tbdxpuserl0_
2015-06-09 09:54:25,555 INFO ClassPathXmlApplicationContext  - Closing org[email protected]2e52cdcc: startup date [Tue Jun 09 09:43:51 CST 2015]; root of context hierarchy
2015-06-09 09:54:25,556 INFO EhCacheManagerFactoryBean  - Shutting down EhCache CacheManager
2015-06-09 09:54:25,574 INFO SimpleHanlder  - Stop socket handler.
2015-06-09 09:54:25,576 INFO LocalContainerEntityManagerFactoryBean  - Closing JPA EntityManagerFactory for persistence unit ‘Oracle‘
2015-06-09 09:54:25,579 INFO ShutDownHook  - Socket server shutdown

此方法可以实现在系统退出时对资源的关闭及缓存数据清理等功能,是一个非常使用的功能。

文中部分内容来自其他博文,代码是我项目中的代码。如有雷同,请勿见怪。

本文只介绍如何使用,至于原理请问度娘和谷歌

时间: 2024-11-09 23:27:42

Java利用ShutDownHook关闭系统资源的相关文章

Java利用POI导入导出Excel中的数据

     首先谈一下今天发生的一件开心的事,本着一颗android的心我被分配到了PB组,身在曹营心在汉啊!好吧,今天要记录和分享的是Java利用POI导入导出Excel中的数据.下面POI包的下载地址http://poi.apache.org/download.html,有兴趣的朋友也可以去看看其中的API.      下面分享一下在对POI进行基本操作时觉得需要注意的两点:       1.POI中针对xlsx/xls是需要create different Workbook instance

Java利用Eclipse和Mysql数据库连接并存储图片——存储图片

import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; public class insertImage {  public static void main(String[]args) throws Ex

【Linux】利用Xvfb关闭chrome的图形化输出

利用Xvfb关闭chrome的图形化输出 #!/bin/bash . /home/fzuir/.profile # JAVA export JAVA_HOME=/usr/local/jdk1.7.0_75 export JRE_HOME=$JAVA_HOME/jre export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar # 利用Xvfb关闭chrome的图形化输出 X

Java利用串口编程技术操作继电器

首先要把环境搭建好,也就是jdk还有tomcat,要是不需要再web上使用就不需要装了! 还有就是配置,也就是默认的comm.jar ,javax.comm.properties , win32com.dll这几个文件要放对地方 comm.jar放到C:\Program Files (x86)\Java\jdk1.7.0_01\jre\lib\ext 同时也放到jre相同目录下 javax.comm.properties放到 C:\Program Files (x86)\Java\jdk1.7.

【转载】 java利用snmp4j包来读取snmp协议数据(Manager端)

https://www.cnblogs.com/xdp-gacl/p/4187089.html http://doc.okbase.net/yuanfy008/archive/265663.html java利用snmp4j包来读取snmp协议数据(Manager端) 1 snmp简单介绍 java利用snmp4j包来读取snmp协议数据,很简单的一个流程,就是利用java来读取运行snmp协议的数据,例如服务器.PC机或者路由器等运行了snmp协议的设备. snmp协议是什么呢? 简单网络管理

Java利用poi生成word(包含插入图片,动态表格,行合并)

转: Java利用poi生成word(包含插入图片,动态表格,行合并) 2018年12月20日 09:06:51 wjw_11093010 阅读数:70 Java利用poi生成word(包含插入图片,动态表格,行合并) 测试模板样式: Word生成结果: 图表 2需要的jar包:(具体jar可自行去maven下载) 注意:需要严格按照上面版本下载jar包,否则可能出现jar包之间不能匹配的导致代码报错 各种 jar包都可以在这里下载: https://mvnrepository.com/ Tes

Java 利用replaceAll 替换中括号

Java的replaceAll函数默认是不能替换中括号的,例如想替换[b]到<b>,结果却就变成[<b>] 解决方案就是首先利用正则表达式替换中括号,然后再替换中括号内的内容: Java代码   infos = infos.replaceAll("[\\[\\]]",""); 不过后来又查询了下资料,发现中括号在java中居然是特殊字符,一对中括号里的内容是一组正则表达式.所以如果打算让[b]-><b>,只要如下写法: Ja

java 利用spring JavaMailSenderImpl发送邮件,支持普通文本、附件、html、velocity模板

java 利用spring JavaMailSenderImpl发送邮件,支持普通文本.附件.html.velocity模板 博客分类: Java Spring 本文主要介绍利用JavaMailSenderImpl发送邮件.首先介绍了发送一般邮件,然后介绍了发送富文本(html)邮件及以velocity为模板发送邮件. 邮件发送分为为三步:创建邮件发送器.编写邮件.发送邮件. Spring的JavaMailSenderImpl提供了强大的邮件发送功能,可发送普通文本邮件.带附件邮件.html格式

java利用pdfbox处理pdf

刚开始以为java读取pdf向读取txt文件一样简单,图样图森普!乱码问题! 在网上找了下资料,发现Apache的PDFBOX,下面写一下PDFBOX读取PDF的代码. 下载jar包:http://pdfbox.apache.org/downloads.html#recent 创建pdf,写入pdf的代码,官网上有介绍:http://pdfbox.apache.org/cookbook/documentcreation.html 直接搬过来 Create a blank PDF This sma