欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

java signal handler_JAVA优雅停机的实现

发布时间:2025/3/15 编程问答 34 豆豆
生活随笔 收集整理的这篇文章主要介绍了 java signal handler_JAVA优雅停机的实现 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

最近在项目中需要写一个数据转换引擎服务,每过5分钟同步一次数据。具体实现是启动engine server后会初始化一个ScheduledExecutorService和一个ThreadPoolExecutor线程池。schduel executor每过5分钟将dataTransformList中每一个tranform加入到线程池中运行。每一个数据转化器负责转换一组数据库数据。在执行过程中存在服务重启并且此时tranform正在转换数据并且数据没有全部操作完,此时希望正在执行的work能正常完成作业后再退出。优雅停机在服务重启,服务关闭显得比较重要了(尽管不能解决服务器突然断电导致服务瞬间不可用等原因)。

普通的优雅停机:当使用kill PID的时候jvm会收到服务停止信号并执行shutdownHook的线程

Runtime.getRuntime().addShutdownHook(new Thread() {

public void run() {

synchronized (EngineBootstrap.class) {

EngineServer.getInstance().shutdown();

running = false;

EngineBootstrap.class.notify();

}

}

});

EngineServer的shutdown方法

public void shutdown() {

this.transformExecutor.shutdown();

this.scheduledExecutorService.shutdown();

}ThreadPoolExecutor的shutdown方法会中断所有的空闲任务,保持正在运行中的任务执行完毕,但是由于kill PID一段时间后jvm就退出了导致正在执行的任务还没有完成就停止了。

改进后的优雅停机:

Signal sig = new Signal(getOSSignalType());

Signal.handle(sig, new SignalHandler() {

public void handle(Signal signal) {

synchronized (EngineBootstrap.class) {

EngineServer.getInstance().shutdown();

running = false;

EngineBootstrap.class.notify();

}

}

});

private static String getOSSignalType() {

return System.getProperties().getProperty("os.name").

toLowerCase().startsWith("win") ? "INT" : "USR2";

}

linux下通过kill -l查看 31 对应于 SIGUSR2 执行kill -31 PID, SignalHander会接收到signal number为31的信号并执行server shutdown,此时jvm并不会退出直到线程池所有正在执行的线程全部执行完毕才会安全退出。

java -jar data-engine-1.0.0-SNAPSHOT.jar

sh shutdown.sh

可以看到主线程安全退出后,线程池中的work执行完毕后java进程才结束

chenbanghongs-MacBook-Pro:nbugs-data-engine sylar$ java -jar target/data-engine-1.0.0-SNAPSHOT.jar.zip

1

2

3

4

5

31

优雅停机

主线程安全退出

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

transform

总结

以上是生活随笔为你收集整理的java signal handler_JAVA优雅停机的实现的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。