文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java优雅停机的实现及原理是什么

2023-06-17 00:22

关注

这篇文章给大家介绍Java优雅停机的实现及原理是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

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

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

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

Java语言中,我们可以通过Runtime.getRuntime().addShutdownHook()方法来注册钩子,以保证程序平滑退出。(其他语言也类似)

来个栗子:

public class ShutdownGraceFullTest {           public static ExecutorService executorService = Executors.newCachedThreadPool();      public static void main(String[] args) {          //假设有5个线程需要执行任务         for(int i = 0; i < 5; i++){             final int id = i;             Thread taski = new Thread(new Runnable() {                 @Override                 public void run() {                     System.out.println(System.currentTimeMillis() + " : thread_" + id + " start...");                     try {                         TimeUnit.SECONDS.sleep(id);                     } catch (InterruptedException e) {                         e.printStackTrace();                     }                     System.out.println(System.currentTimeMillis() + " : thread_" + id + " finish!");                 }             });             taski.setDaemon(true);             executorService.submit(taski);         }          // 添加一个钩子处理未完任务         Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {             @Override             public void run() {                  System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " No1 shutdown hooking...");                 boolean shutdown = 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 (InterruptedException e) {                     e.printStackTrace();                 }                 System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " No1 shutdown done...");             }         }));          // 多个关闭钩子并发执行         Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {             @Override             public void run() {                 try {                     System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " No2 shutdown hooking...");                     Thread.sleep(1000);                 } catch (InterruptedException e) {                     e.printStackTrace();                 }                 System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " No2 shutdown done...");             }         }));          System.out.println("main method exit...");         // 故意调用jvm退出命令,发送关闭信号,否则正常情况下 jvm 会等待***一个非守护线程关闭才会退出         System.exit(0);     } }

运行结果如下:

Java优雅停机的实现及原理是什么

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

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

kill -15 pid

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

  1. 关闭 socket 链接

  2. 清理临时文件

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

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

  5. 各种资源的释放

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

kill -9 pid

如果这么干的话,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 也不能保证线程一定停止运行)。

注意:

关于Java优雅停机的实现及原理是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯