- 浏览: 374611 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
真的全站唯一:
描述的能不能准确一点,我也以为bigDecimal性能比dou ...
【性能】Java BigDecimal和double性能比较 -
zhanggang807:
学习到了。。以后会考虑往这方面设计
【java规范】Java spi机制浅谈 -
Xiong506:
xiyuan1025 写道你这是在linux下吗,我在linu ...
[监控]Btrace监控简单笔记 -
Xiong506:
xiyuan1025 写道你这是在linux下吗,我在linu ...
[监控]Btrace监控简单笔记 -
Bll:
找不到实现类
【java规范】Java spi机制浅谈
java应用程序退出的触发机制有:
1.自动结束:应用没有存活线程或只有后台线程时;
2.System.exit(0);
3.kill 或 ctrl+C;
4.kill -9 强制退出;
如何做到应用程序平滑停止
程序的退出就像关机一样,我们希望关机时平滑关机,保证所有应用程序的数据都保存了。就像现在在写得blog,希望关机的时候能被保存好到草稿箱里。
我们的的java程序中经常有一种常驻的任务或服务,如消息消费端、服务提供者,我们期望停止也是平滑的不会出现事务执行到一半产生脏数据。
java对这块的支持是通过钩子线程实现。每个java进程都可以注册钩子线程,钩子线程程在程序退出的前被执行(kill -9强制退出除外)。注册钩子线程代码如下:
Runtime.getRuntime().addShutdownHook(t);
我们可以在钩子线程里做一些善后数据清理等事情,以保证程序是平滑退出的。
一般服务或框架运行都要考虑其生命周期:
如spring容器的context.stop()方法。
再如线程池ExecutorService的shutdown方法,它会保证不接受新任务,并把未执行完的任务做完。
我们再设计服务的时候也要考虑到停止时的stop方法,以便于退出时由钩子线程调用。
注册了钩子线程后,程序收到退出信号后,会保持程序运行,直到钩子线程执行完毕,才把程序的所有线程停止并退出,下面示例代码可以说明这一点:
public class ShutDownTest { public static void main(String[] args) { //注册第一个钩子 Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { try { Thread.currentThread().sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("clean task1 completed."); } }); //注册第二个钩子 Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { try { Thread.currentThread().sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("clean task2 completed"); } }); //启动子线程 new Thread() { public void run() { while (true) { try { Thread.currentThread().sleep(1000); System.out.println("sub thread is running"); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); //程序退出 System.exit(0); } }
程序输出:
sub thread is running sub thread is running sub thread is running sub thread is running clean task1 completed. sub thread is running sub thread is running sub thread is running sub thread is running sub thread is running clean task2 completed
===============================================================================
注意点 :钩子线程里只处理善后,目标是尽可能快的退出且不保证有脏数据。如果钩子线程里做过多事情,或者发生阻塞,那么可能出现kill失效,程序不能退出的情况,这是需要强制退出。
如以下程序会导致kill失效,需要强制退出,因为钩子线程阻塞了:
public class ShutDownTest { public static void main(String[] args) { //注册钩子 Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { synchronized (ShutdownFileTest.class) { try { ShutdownFileTest.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }); //启动子线程 new Thread() { public void run() { while (true) { try { Thread.currentThread().sleep(1000); System.out.println("sub thread is running"); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); System.exit(0); } }
程序退出机制选择
触发程序退出的在前面已经提到过,但是为了停止方便、安全和优雅,一般我们推荐几种操控性更强的退出机制。常见的推荐机制有以下几种:
1.kill
在linux里用的比较多,向进程发送退出信号,java进程收到后平滑退出。
2.shutdownfile
系统创建一个shutdown file.并监听shutdown file是否存在。如果发现shutdown file不存在了,那么调用System.exit,将程序退出。
如果期望只有特定的人才能终止该程序,那么你可以给文件设定权限,这样就只有特定的人可以终止程序。
以下代码是个简单的例子:
import java.io.File; import java.io.IOException; public class ShutdownFileTest { public static void main(String[] args) { // 启动子线程 new Thread() { public void run() { while (true) { try { Thread.currentThread().sleep(1000); System.out.println("sub thread is running"); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); //启动shutdownfile监听线程 new Thread() { public void run() { File shutDownFile = new File("a.shutdown"); // create shut down file if (!shutDownFile.exists()) { try { shutDownFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } // watch for file deleted then shutdown while (true) { try { if (shutDownFile.exists()) { Thread.currentThread().sleep(1000); } else { System.exit(0); } } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } }
3.打开一个端口,监听端口里的命令,收到命令后调用System.exit。
这个似乎不常见,也比较麻烦。
4.JMX
通过JMX的mbean远程控制来实现。
在这个链接里有看到例子:how-to-stop-java-process-gracefully
评论
1. kill pid
2.触发jvm的addShutdownHook。
3.如果在spring容器中,触发springbean的destroy-method回调方法。
但不同的应用场景要做到平滑停止面临不一样的问题,比如一台服务Server,不断有请求过来,如果要停止,已经执行一半的事务应该如何处理,如何平滑停止保证不会产生脏数据?期待博主能有更深入的分析。
发表评论
-
【java规范】Java spi机制浅谈
2012-04-24 23:04 45695最近看到公司的一些框架和之前看到的开源的一些框架的一些服务发现 ... -
Xml ResourceBundle简单实现
2012-04-17 21:45 4359ResourceBundle主要是用于和本地语言环境相关的一些 ... -
【maven】多子模块maven模板工程archetype创建过程
2012-04-02 20:55 17546最近项目里需要创建一 ... -
【java并发】juc Executor框架详解
2012-02-26 13:55 12359Executor 框架是 juc 里提供的线程池的实现。 ... -
【java并发】juc高级锁机制探讨
2012-02-23 00:52 8486最近在看一些j ... -
【java并发】基于JUC CAS原理,自己实现简单独占锁
2012-02-14 13:47 7755synchronized的基本原理回 ... -
[NoSQL]MongoDB初体验
2012-01-05 16:06 3916因为未来业务发展的一 ... -
【JDBC,数据库】Oracle date和timestamp类型混用时需要注意的索引失效问题
2011-12-14 15:27 88421.关于 Oracle date和timestamp类型 D ... -
【JVM】HotSpot JVM内存管理和GC策略总结
2011-12-13 22:05 15871JVM的相关知识是学习java ... -
【性能】JDBC PreparedStatement和连接池PreparedStatement Cache学习记录
2011-12-08 17:20 16738之前看JDBC规范的时候对PreparedStatement只 ... -
32位机器下的一个java.lang.OutOfMemoryError错误分析
2011-10-17 11:19 2543昨天在本人windows机器( ... -
【Spring】IOC核心源码学习(三):bean标签和自定义标签实现原理
2011-09-25 11:13 9609接上文: 【Spring】IOC核心源码学习(二):容器初始 ... -
【Spring】IOC核心源码学习(二):容器初始化过程
2011-09-21 21:03 23474接上文 啃啃老菜: Spring IOC核心源码学习(一 ... -
[监控]Btrace监控简单笔记
2011-09-09 10:57 4886前阵子看了公司网站的一个cache 命中率统计的btrace监 ... -
DBCP数据源配置项记录
2011-09-01 20:22 2925网站最近发生了数据库连接爆掉的问题。排查了下各个应用存在 ... -
【性能】Java BigDecimal和double性能比较
2011-08-28 20:06 14094我们知道 java 里面有个 BigDecimal ... -
【Spring】IOC容器并发条件下,可能发生死锁
2011-08-28 17:07 68231.背景 上周在生产环境应用启 ... -
JDK7 AIO 初体验
2011-08-17 19:20 2525JDK7 AIO初体验 JDK7已经releas ... -
啃啃老菜:Spring IOC核心源码学习(一)
2011-08-14 13:57 7437啃啃老菜: Spring IOC核心源码 ... -
如果要用java实现算法,一定慎用递归
2011-04-06 20:41 12804现象 : 递归是我们很经典的一种算法实现,可以很好的 ...
相关推荐
手机-java-应用程序-函数曲线-绘制程序-GraphViewer
数字图像处理 JAVA 边缘检测 图像增强 图像分割 平滑 有界面 图像变换
java代码实现指数平滑算法,其中包括一次,二次,三次
《GPS应用程序设计》源代码。本软件是专为《GPS应用程序设计》一书配套发行的。包括: 1、 data_log.c 数据采集程序 2、 rinexout.c RINEX数据格式写入子程序 3、 to_rinex.c 数据格式转换 4、 sav_pos.c 卫星位置...
《GPS应用程序设计》书籍源代码 《GPS应用程序设计》源代码。本软件是专为《GPS应用程序设计》一书配套发行的。包括: 1、 data_log.c 数据采集程序 2、 rinexout.c RINEX数据格式写入子程序 3、 to_rinex.c 数据...
java编写的轨迹纠偏算法,包含异常点检测、滤波平滑,以及代码使用示例和结果分析
指数平滑用来做时间序列预测,数据是单个时间序列,输入数据格式为二维数据, 一维数据,只需定义一个一行多列的数组即可
**Java毕业设计:Java图形图像处理系统** 本文档及所附系统为Java毕业设计的成果,旨在提供一个基于Java的图形图像处理解决方案。文档详细介绍了系统的设计思路、功能实现及关键技术,包括图像读取、显示、编辑和...
在本章的学习过程中,建议读者实际运行所讨论的applet程序和应用程序。在画图时,有时是一次只画一条线,而有时是将图像一次全部画出来;有的图像在显示的过程中不停地闪烁,而一些图像则是很平滑地显示。所有...
数据文件已经项目目录下,直接在IDE导入项目运行即可。(注:该项目是在jdk1.8环境下编译) 数据文件已经项目目录下,直接在IDE导入项目运行即可。(注:该项目是在jdk1.8环境下编译)
Sociogram - 社交媒体应用程序 | Instagram 卷轴 |主题 |会所|聊天 |社交网络应用程序项目源码 Sociogram 是一款社交媒体应用程序,包含各种功能来增强您的在线社交体验。借助 Sociogram,您可以创建和分享类似于 ...
本文首先对图像增强和图像分割中的几种算法进行了介绍,包括线性灰度变换,伪...然后用Java语言对上述各算法编程实现,并设计Java GUI(图形用户界面)用来显示图像处理的结果,以及创建一个数据库用于存储医学图像。
基于CUDA平台的9点平滑、高斯平滑代码
平滑滤波器设计应用.doc
摘 要 随着计算机技术的迅速发展,数字图像处理...然后用Java语言对上述各算法编程实现,并设计Java GUI(图形用户界面)用来显示图像处理的结果,以及创建一个数据库用于存储医学图像。 关键词:医学图像;图像增强
连续提取AD数据,平滑滤波后再作FIR处理。
图像处理程序中的高斯平滑源码,去噪能力好,
JAVA语言编写的小型数字图像处理程序,包含改变采样率、量化等级,显示直方图、直方图均衡、图像旋转、平滑等基本操作
CrazyArcade泡泡堂游戏,一款用Java编写的JavaSwing游戏程序。 使用了MVC模式,分离了模型、视图和控制器,使得项目结构清晰易于扩展,使用配置文件来设置游戏基本配置,扩展地图人物道具等。同时,该程序编写期间用...
java编写的图像处理程序+源代码+文档 支持灰度图处理、对比度处理、亮度处理、直方图均衡化、灰度直方图、直方图匹配、锐化处理、平滑化处理