如何优雅的停止服务(ShutdownHook)
来源:互联网 发布:杭州seo 编辑:程序博客网 时间:2024/05/20 16:44
JDK提供了Runtime.addShutdownHook(Thread hook)方法用来注册一个钩子(线程),在Java程序退出时会调用这个钩子来清理现场。
这个钩子会在以下场景中被调用:
1. 程序正常退出
2. 使用System.exit()
3. 终端使用Ctrl+C触发的中断
4. 系统关闭
5. OutOfMemory宕机
6. 使用Kill pid命令干掉进程(注:在使用kill -9 pid时,是不会被调用的)
下面我们来简单的模拟一个服务,详细说明如何优雅的终止Java进程。
/** * zyc 2017年10月16日 下午3:05:03 */public class ShutdownHookTest{ private static ExecutorService executorService = Executors.newFixedThreadPool(10); private static final long TIMEOUT = 10 * 1000; public static void main(String[] args) { // 注册钩子函数,在JVM接收到停止指令后会运行该线程 Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { @Override public void run() { System.out.println("invoke shutdownhook ...."); // 调用该方法把threadpool 的 shutdown 设置为true,不再接受提交任务, // 等待已经提交的任务执行完之后才会退出 executorService.shutdown(); long time = System.currentTimeMillis(); while(true){ int activeCount = ((ThreadPoolExecutor)executorService).getActiveCount(); // 执行中的线程数 int waitCount = ((ThreadPoolExecutor)executorService).getQueue().size(); // 等待的线程数 System.out.println("there are " + waitCount + " threads wait ...."); System.out.println("there are " + activeCount + " threads working ...."); if(executorService.isTerminated()){ // 等待线程池退出 System.out.println("thread pool is shutdown ..."); break; } if(System.currentTimeMillis() - time > TIMEOUT) // 超时 executorService.shutdownNow(); sleep(500); } } })); // 模拟工作环境,不断往线程池提交任务 for(;;){ if(executorService.isShutdown()) break; executorService.submit(new Runnable() { @Override public void run() { String name = Thread.currentThread().getName(); System.out.println(name + " work ...."); sleep(2 * 1000); // 模拟线程工作 } }); sleep(500); } } private static void sleep(long millis){ try { TimeUnit.MILLISECONDS.sleep(millis); } catch (InterruptedException e) { e.printStackTrace(); } }}
把代码打成Jar包在linux上运行 java –jar ShutdownHookTest.jar,输出如下:
线程池在持续工作,并不断的有任务提交。
执行kill命令终止Java进程
注意:这里用的是kill -15 pid 不是kill -9 pid
Java进程接收到终止指令后,调用钩子方法,直到线程池里的所有任务都执行完毕才退出
本文简单的模拟了关闭服务的场景,通过不断的轮询线程池的状态,直到所有提交的任务执行完毕才终止进程,清理的逻辑在钩子函数的run方法中实现即可,更多的功能请各位自己尝试。
阅读全文
0 0
- 如何优雅的停止服务(ShutdownHook)
- SparkStreaming如何优雅的停止服务
- Spark Streaming优雅的停止服务
- JVM安全退出(如何优雅的关闭java服务)
- 如何停止weblogic服务
- 如何停止AAD服务
- SpringCloud服务如何在Eureka安全优雅的下线
- 关闭钩子(ShutdownHook)
- ShutdownHook
- ShutdownHook
- ShutdownHook
- shutdownHook
- ShutdownHook
- 如何启动/停止NOC服务
- 服务(Service)的停止和启动
- Linux攻略 如何修改系统的服务启动和停止
- 如何一个命令停止某个端口的服务进程
- LINUX下如何修改系统的服务启动和停止
- Quicker.em 的函数内容
- 最完美ThinkPHP Nginx 配置文件
- 编程找出1000以内的完数,并按下面格式输出因子:6 its factors are 1 2 3
- Web页面的数据导出excel时的格式问题
- SpringBoot Thymeleaf web实例
- 如何优雅的停止服务(ShutdownHook)
- Linux(Centos)之安装Nginx及注意事项
- eclipse构建maven项目整合SSM(spring+springMVC+mybatis)框架
- npm install 时遇到的Python问题
- laravel homestead windows 安装 no input file specified解决办法
- Javascript Array和String的互转换
- [栈 二分图染色] NOIP2008 双栈排序
- centos设置内核启动顺序
- android高德地图自定义infoWindow没有显示出来