优雅停机?这个名词我是服的,如果抛开专业不谈,多好的名词啊!

其实优雅停机,就是在要关闭服务之前,不是立马全部关停,而是做好一些善后操作,比如:关闭线程、释放连接资源等。

再比如,就是不会让调用方的请求处理了一增,一下就中断了。而处理完本次后,再停止服务。

Java语言中,我们可以通过

Runtime.getRuntime().addShutdownHook()

方法来注册钩子,以保证程序平滑退出。(其他语言也类似)

来个栗子:publicclassShutdownGraceFullTest{

/**

* 使用线程池处理任务

*/

publicstaticExecutorServiceexecutorService =Executors.newCachedThreadPool();

publicstaticvoidmain(String[] args) {

//假设有5个线程需要执行任务

for(inti =0; i <5; i++){

finalintid = i;

Threadtaski =newThread(newRunnable() {

@Override

publicvoidrun() {

System.out.println(System.currentTimeMillis() +" : thread_"+ id +" start...");

try{

TimeUnit.SECONDS.sleep(id);

}catch(InterruptedExceptione) {

e.printStackTrace();

}

System.out.println(System.currentTimeMillis() +" : thread_"+ id +" finish!");

}

});

taski.setDaemon(true);

executorService.submit(taski);

}

// 添加一个钩子处理未完任务

Runtime.getRuntime().addShutdownHook(newThread(newRunnable() {

@Override

publicvoidrun() {

System.out.println(System.currentTimeMillis() +" : "+Thread.currentThread().getName() +" No1 shutdown hooking...");

booleanshutdown =true;

try{

executorService.shutdown();

System.out.println(System.currentTimeMillis() +" : "+Thread.currentThread().getName() +" shutdown signal got, wait threadPool finish.");

executorService.awaitTermination(1500,TimeUnit.SECONDS);

System.out.println(System.currentTimeMillis() +" : "+Thread.currentThread().getName() +" all thread's done.");

}

catch(InterruptedExceptione) {

e.printStackTrace();

}

System.out.println(System.currentTimeMillis() +" : "+Thread.currentThread().getName() +" No1 shutdown done...");

}

}));

// 多个关闭钩子并发执行

Runtime.getRuntime().addShutdownHook(newThread(newRunnable() {

@Override

publicvoidrun() {

try{

System.out.println(System.currentTimeMillis() +" : "+Thread.currentThread().getName() +" No2 shutdown hooking...");

Thread.sleep(1000);

}catch(InterruptedExceptione) {

e.printStackTrace();

}

System.out.println(System.currentTimeMillis() +" : "+Thread.currentThread().getName() +" No2 shutdown done...");

}

}));

System.out.println("main method exit...");

// 故意调用jvm退出命令,发送关闭信号,否则正常情况下 jvm 会等待最后一个非守护线程关闭才会退出

System.exit(0);

}

}

运行结果如下:

很明显,确实是优雅了,虽然最后收到了一关闭信号,但是仍然保证了任务的处理完成。很棒吧!

那么,在实际应用中是如何体现优雅停机呢?kill -15pid

通过该命令发送一个关闭信号给到jvm, 然后就开始执行 Shutdown Hook 了,你可以做很多:

1、 关闭 socket 链接

2、 清理临时文件

3、 发送消息通知给订阅方,告知自己下线

4、 将自己将要被销毁的消息通知给子进程

5、 各种资源的释放

...

而在平时工作中,我们不乏看到很多运维同学,是这么干的:kill -9pid

如果这么干的话,jvm也无法了,kill -9 相当于一次系统宕机,系统断电。这会给应用杀了个措手不及,没有留给应用任何反应的机会。

所以,无论如何是优雅不起来了。

要优雅,是代码

其中,线程池的关闭方式为:executorService.shutdown();

executorService.awaitTermination(1500,TimeUnit.SECONDS);

ThreadPoolExecutor 在 shutdown 之后会变成 SHUTDOWN 状态,无法接受新的任务,随后等待正在执行的任务执行完成。意味着,shutdown 只是发出一个命令,至于有没有关闭还是得看线程自己。

ThreadPoolExecutor 对于 shutdownNow 的处理则不太一样,方法执行之后变成 STOP 状态,并对执行中的线程调用 Thread.interrupt() 方法(但如果线程未处理中断,则不会有任何事发生),所以并不代表“立刻关闭”。

shutdown() :启动顺序关闭,其中执行先前提交的任务,但不接受新任务。如果已经关闭,则调用没有附加效果。此方法不等待先前提交的任务完成执行。

shutdownNow():尝试停止所有正在执行的任务,停止等待任务的处理,并返回正在等待执行的任务的列表。当从此方法返回时,这些任务将从任务队列中耗尽(删除)。此方法不等待主动执行的任务终止。

executor.awaitTermination(this.awaitTerminationSeconds, TimeUnit.SECONDS)); 控制等待的时间,防止任务无限期的运行(前面已经强调过了,即使是 shutdownNow 也不能保证线程一定停止运行)。

注意:

虚拟机会对多个shutdownhook以未知的顺序调用,都执行完后再退出。

如果接收到 kill -15 pid 命令时,执行阻塞操作,可以做到等待任务执行完成之后再关闭 JVM。同时,也解释了一些应用执行 kill -15 pid 无法退出的问题,如:中断被阻塞了,或者hook运行了死循环代码。

出处:https://dwz.cn/nRS7c1Zg

—————END—————

关注公众号,查看更多优质文章

java唱歌打分系统原理_哦,这就是java的优雅停机?(实现及原理)相关推荐

  1. java自动生成代码原理_原来这就是Java代码生成器的原理啊,太简单了

    前几天写了篇关于代码生成器的文章(可查看历史文章),不少同学私下问我这个代码生成器是如何运作的,为什么要用到一些模板引擎,所以今天来说明下代码生成器的流程. 2. 代码生成器的使用场景 我们在编码中存 ...

  2. java native 原理_一种Java+Native应用的系统架构的制作方法

    本发明涉及智能卡技术领域,特别是要求支持Java功能的智能卡领域. 背景技术: Java卡是Sun微系统为智能卡开发平台而制定的一个开放的标准.使用Java卡平台创建的智能卡上存有Java apple ...

  3. java stringbuffer原理_深入理解Java:String

    在讲解String之前,我们先了解一下Java的内存结构. 一.Java内存模型 按照官方的说法:Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配. JVM主要管理两 ...

  4. java面试宝典有用么_常见的Java面试题汇总

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 二.关于集合 1.Java中的集合及其继承关系 关于集合的体系是每个人都应该烂熟于心的,尤其是对我们经常使用的List,Map的原理更该如此. 2.pol ...

  5. java 面试题合集_撩课-Java面试题合辑1-50题

    1.简述JDK.JRE.JVM? 一.JDK JDK(Java Development Kit) 是整个JAVA的核心, 包括了Java运行环境(Java Runtime Envirnment), 一 ...

  6. java带参数的构造方法_看了Java的Class的源码,我自闭了

    作者丨chenweicool 来源:https://www.cnblogs.com/chentang/p/13170081.html 1.class这个类是什么 Class的本质也是一个类,只不过它是 ...

  7. java不会框架怎么办_感觉学java无从下手了,各种框架乱七八糟,感觉好乱。该怎么办!?...

    image 各种各样的编程语言不断崛起,但唯有Java是牢牢占据着老大的位置,目前几乎90%以上的大中型互联网应用系统在服务器端开发首选Java.因此,也是吸引了不少年轻人投入到Java的学习之中. ...

  8. 《跟旺旺老师学Java》_第一章Java简介与JDK部署_第一部分Java是什么

    第一章:Java简介与JDK部署 第一部分:java是什么 "是白云,是瀑布,是海滩,不---,都不是,这是太原大理石二厂生产的景云牌大理石"看到这个标题,脑海中莫名的闪过这句小时 ...

  9. 有谁转行学java成功了的吗_转行学习java靠谱吗?

    转行学Java靠谱吗?靠不靠谱主要还是看你自己是否想要学好Java技术,是否想要从事这方面的岗位工作,如果你已经有了这个决心,那么自然而然什么都不会问题.无论我们学Java是兴趣还是想要通过学好Jav ...

最新文章

  1. CSS学习笔记(二) ----盒子模型
  2. const指针 常指针
  3. windows10 + Anaconda搭建tensorflow-gpu环境
  4. Mysql5换成Mysql8之后报错java.lang.ClassNotFoundException: com.mysql.jdbc.driver的问题解决
  5. 复杂产品的响应式设计【知识篇】
  6. layui 图片展示添加一个x_Layx 演示示例
  7. 分布式事务控制解决方案
  8. JAVA企业级应用服务器之TOMCAT实战
  9. linux 子shell
  10. C#小游戏-------猜数字(转载)
  11. 2021-08-27
  12. 专升本计算机综合-数据结构篇
  13. HD、BD、MKV和RMVB、DVD、AVI
  14. AutoML 前瞻与实践 ---- AutoML 简介
  15. 洛谷【P1359】租用游艇
  16. 如何提高仓库操作管理效率?
  17. 模电一、半导体二极管和三极管
  18. 好书推荐:《黑客秘笈:渗透测试实用指南》
  19. 编译tensorflow1.15.4,使其支持AVX2 和 FMA
  20. 金投网煤炭数据爬取-精进版

热门文章

  1. ae计算机安装步骤,ae插件怎么安装【设置步骤】
  2. matlab 画波特图
  3. 火箭发射问题_人工智能有火箭问题
  4. js实现PDF在线预览
  5. JAVAWEB天气预报 中国气象网API(WebServices)
  6. Playmaker学习记录二
  7. 降雨量预测血吸病虫风险
  8. Background concurrent copying GC freed 107384(8MB) AllocSpace objects, 0(0B) LOS objects, 49% 原因記錄
  9. Little VGL(LVGL)图形库移植到CH32V307单片机(一)
  10. 计算机在盲童音乐教学中的具体应用,盲童钢琴教学实践和教学方法探究-特殊教育论文-教育论文.docx...