建设工程职称 在哪个网站,苏州网站开发公司兴田德润放心,wordpress用qq登录界面,杭州网站备案要多久文章目录 一.ShutdownHook介绍二.ShutdownHook被调用场景三.ShutdownHook如何使用四.ShutdownHook实践 一.ShutdownHook介绍 ShutdownHook就是一个简单的 已初始化 但是 未启动 的 线程 。当虚拟机开始关闭时#xff0c;它将会调用所有已注册ShutdownHook的回调函数#xff0… 文章目录 一.ShutdownHook介绍二.ShutdownHook被调用场景三.ShutdownHook如何使用四.ShutdownHook实践 一.ShutdownHook介绍 ShutdownHook就是一个简单的 已初始化 但是 未启动 的 线程 。当虚拟机开始关闭时它将会调用所有已注册ShutdownHook的回调函数这些回调函数执行是并发的执行顺序是不确定的。 作用JVM退出时执行的业务逻辑 注意ShutdownHook方法参数必须是Thread的子类由此得知ShutdownHook是异步执行的。 添加Runtime.getRuntime(). addShutdownHook(Thread var1)移除Runtime.getRuntime().removeShutdownHook(this.shutdownHookThread) 需要注意的是在ShutdownHook里执行的操作应当是不太耗时的。因为在用户注销或者操作系统关机导致的JVM shutdown的例子中系统只会预留有限的时间给未完成的工作超时之后还是会强制关闭。
二.ShutdownHook被调用场景
程序正常退出程序调用 System.exit() 退出终端使用 CtrlC 中断程序程序抛出异常导致程序退出例如 OOM数组越界等异常系统事件例如用户注销或关闭系统使用 Kill pid 命令杀掉进程注意使用 kill -9 pid 强制杀掉不会触发执行钩子
三.ShutdownHook如何使用
调用java.lang.Runtime这个类的addShutdownHook(Thread hook)方法即可注册一个ShutdownHook然后在Thread中定义需要在system exit时进行的操作。如下
Runtime.getRuntime().addShutdownHook(new Thread(() - System.out.println(Do something in ShutdownHook)
));
测试例子
首先注册了一个ShutdownHook。 然后系统Sleep 3秒模拟进行某些操作。 然后调用一个空的List抛出异常准备结束程序。 在程序将要结束的时候执行ShutdownHook中的内容。
public static void main(String[] args)
{// register ShutdownHookRuntime.getRuntime().addShutdownHook(new Thread(() - System.out.println(Do something in ShutdownHook)));// sleep for some timetry {for (int i0; i3; i) {System.out.println(Count: i ...);TimeUnit.MILLISECONDS.sleep(1000);}List nullList new ArrayList();System.out.println(Trying to print null lists first element: nullList.get(0).toString());} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Ready to exit.);System.exit(0);
}结果如下
Count: 0...
Count: 1...
Count: 2...
Exception in thread main java.lang.IndexOutOfBoundsException: Index: 0, Size: 0at java.util.ArrayList.rangeCheck(ArrayList.java:653)at java.util.ArrayList.get(ArrayList.java:429)at HookTest.main(HookTest.java:18)
Do something in ShutdownHookProcess finished with exit code 1需要注意的点
当System.exit之后当ShutdownHook开始执行时其他的线程还是会继续执行。应当保证ShutdownHook的线程安全。 在使用多个ShutdownHook时一定要特别小心保证其调用的服务不会被其他Hook影响。否则会出现当前Hook所依赖的服务被另外一个Hook终止了的情况。
四.ShutdownHook实践
例如我们程序自定义了一个线程池用来接收和处理任务。如果程序突然崩溃异常退出这时线程池的所有任务有可能还未处理完成如果不处理完程序就直接退出可能会导致数据丢失业务异常等重要问题。这时钩子就派上用场了。 import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;public class ShutdownHookDemo {// 线程池private static ExecutorService executorService Executors.newFixedThreadPool();static {Runtime.getRuntime().addShutdownHook(new Thread(() - {System.out.println(开始执行钩子方法...);// 关闭线程池executorService.shutdown();try {// 等待秒System.out.println(executorService.awaitTermination(, TimeUnit.SECONDS));} catch (InterruptedException e) {e.printStackTrace();}System.out.println(结束执行钩子方法...);}));}public static void main(String[] args) throws InterruptedException {System.out.println(程序开始启动...);// 向线程池添加个任务for (int i ; i 10; i) {Thread.sleep();final int finalI i;executorService.execute(() - {try {Thread.sleep();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Task finalI execute...);});System.out.println(Task finalI is in thread pool...);}}
} 在命令行窗口中运行程序在10个任务都提交到线程池之后任务都还未处理完成之前使用CtrlC中断程序最终在虚拟机关闭之前调用了关闭回调函数关闭线程池并且等待60秒让所有任务执行完成。