Java应用程序退出的触发机制有:
创新互联公司服务项目包括古浪网站建设、古浪网站制作、古浪网页制作以及古浪网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,古浪网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到古浪省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
如何做到应用程序平滑停止
程序的退出就像关机一样,我们希望关机时平滑关机,保证所有应用程序的数据都保存了。就像现在在写得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
本文标题:设计Java应用程序的平滑停止
网页路径:http://www.mswzjz.cn/qtweb/news12/57262.html
攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能