高并发编程-Runtime.getRuntime().addShutdownHook为自己的应用添加hook

简介: 高并发编程-Runtime.getRuntime().addShutdownHook为自己的应用添加hook

20191031000807448.png

概述


20191016135043756.png

一句话概括就是: ShutdownHook允许开发人员在JVM关闭时执行相关的代码。

我们可以使用java.lang.Runtime.getRuntime().addShutdownHook(Thread t)方法在JVM中添加关闭钩子。


使用场景


1.程序正常退出 , JVM关闭


2. 调用System.exit ,JVM关闭


3. 程序抛出异常,导致JVM关闭


4. OOM 导致JVM关闭


5. 外界:Ctrl + C ,导致JVM关闭


6. 外界:用户注销或者关机,导致JVM关闭


7. 外界:kill 信号 (kill -9 除外)


8. …


注意事项


1. 可以使用addShutdownHook()添加多个shutdown hooks


2. Shutdown hooks 是initialized 但是 not-started的线程,当JVM关闭时被触发


3. 无法确定shutdown hooks的执行顺序,就像执行多线程一样。


4. 无法保证shutdown hooks会执行,例如系统崩溃,kill命令等。因此,应仅将其用于紧急情况下,例如确保释放关键资源等。不要执行耗时操作


5. 可以使用Runtime.getRuntime().removeShutdownHook(hook)方法删除钩子。


6. 启动关闭挂钩后,无法删除,否则抛出IllegalStateException。


7. 如果存在security manager并且它拒绝RuntimePermission(“shutdownHooks”),则将抛出SecurityException。


示例

package com.artisan.test;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
 *  Runtime.getRuntime().addShutdownHook Demo
 */
public class FileHandler {
    public static String status = "STOPPED";
    public static String fileName = "";
    public static void main(String[] args) {
        // 添加HOOK
        Runtime.getRuntime().addShutdownHook(new FileHandlerHook());
        Runtime.getRuntime().addShutdownHook( new Thread(()->{
            System.out.println("HOOK TRIGGERED:多个shutdown hook 被触发...");
        }));
        // 文件目录
        String directory = "E:\\hooktest";
        File dir = new File(directory);
        // 列出txt结尾的文件
        File[] txtFiles = dir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                if (name.endsWith(".txt")) {
                    return true;
                } else {
                    return false;
                }
            }
        });
        // 模拟触发Hook的情况 case 1
        //System.exit(0);
        // 模拟触发Hook的情况 case 2
        //int a = 1 / 0 ;他
        // OOM
//        List list = new ArrayList();
//        for(int i=0;i<Integer.MAX_VALUE;i++){
//            list.add(i+"测试oom 导出jvm退出,触发hook");
//        }
        // 遍历数组 读取文件
        for (File file : txtFiles) {
            System.out.println("fileName:" + file.getName());
            status = "START";
            BufferedReader bufferedReader = null;
            try {
                FileReader fileReader = new FileReader(file);
                // BufferedReader一行行的读 提高读取效率
                bufferedReader = new BufferedReader(fileReader);
                String line;
                // 先读取一行
                line = bufferedReader.readLine();
                // 循环读取 直到读取完成
                while (line != null) {
                    System.out.println(line);
                    // 模拟业务 休眠一会 方便操作
                    Thread.sleep(1_111);
                    line = bufferedReader.readLine();
                }
                status = "PROCESSED";
            } catch (IOException | InterruptedException e) {
                status = "ERROR";
                e.printStackTrace();
            } finally {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        status = "FINISHED";
    }
    private static class FileHandlerHook extends Thread {
        @Override
        public void run() {
            System.out.println("Status="+FileHandler.status);
            System.out.println("FileName="+FileHandler.fileName);
            if(!FileHandler.status.equals("FINISHED")){
                System.out.println("HOOK TRIGGERED:Seems some error, sending alert....");
            }else{
                System.out.println("HOOK TRIGGERED:handle file over , Do Something notify....");
            }
        }
    }
}


上述代码以及覆盖了使用场景中的事项 ,使用哪个来做验证,放开对应注释即可。

OOM的测试,请设置jvm参数 -Xms10m -Xmx10m , 亲测有效,就不贴图了,自行验证即可。

相关文章
|
8月前
|
安全 Java 编译器
高并发编程之什么是 JUC
高并发编程之什么是 JUC
64 1
|
8月前
|
存储 缓存 安全
高并发编程之阻塞队列
高并发编程之阻塞队列
62 1
|
8月前
|
监控 Java 数据处理
【Spring云原生】Spring Batch:海量数据高并发任务处理!数据处理纵享新丝滑!事务管理机制+并行处理+实例应用讲解
【Spring云原生】Spring Batch:海量数据高并发任务处理!数据处理纵享新丝滑!事务管理机制+并行处理+实例应用讲解
|
8月前
|
存储 Java
高并发编程之多线程锁和Callable&Future 接口
高并发编程之多线程锁和Callable&Future 接口
94 1
|
8月前
|
缓存 监控 Java
高并发编程之ThreadPool 线程池
高并发编程之ThreadPool 线程池
92 1
|
7月前
|
安全 测试技术 Go
Go语言在高并发场景下的应用
在当今互联网高速发展的时代,高并发已成为众多应用系统面临的核心问题。本文探讨了Go语言在高并发场景下的优势,并通过具体实例展示了其在实际应用中的效果和性能表现。
|
3月前
|
并行计算 算法 搜索推荐
探索Go语言的高并发编程与性能优化
【10月更文挑战第10天】探索Go语言的高并发编程与性能优化
|
4月前
|
网络协议 Java Linux
高并发编程必备知识IO多路复用技术select,poll讲解
高并发编程必备知识IO多路复用技术select,poll讲解
|
3月前
|
Java Linux 应用服务中间件
【编程进阶知识】高并发场景下Bio与Nio的比较及原理示意图
本文介绍了在Linux系统上使用Tomcat部署Java应用程序时,BIO(阻塞I/O)和NIO(非阻塞I/O)在网络编程中的实现和性能差异。BIO采用传统的线程模型,每个连接请求都会创建一个新线程进行处理,导致在高并发场景下存在严重的性能瓶颈,如阻塞等待和线程创建开销大等问题。而NIO则通过事件驱动机制,利用事件注册、事件轮询器和事件通知,实现了更高效的连接管理和数据传输,避免了阻塞和多级数据复制,显著提升了系统的并发处理能力。
79 0
|
5月前
|
存储 缓存 安全
.NET 在金融行业的应用:高并发交易系统的构建与优化之路
【8月更文挑战第28天】在金融行业,交易系统需具备高并发处理、低延迟及高稳定性和安全性。利用.NET构建此类系统时,可采用异步编程提升并发能力,优化数据库访问以降低延迟,使用缓存减少数据库访问频率,借助分布式事务确保数据一致性,并加强安全性措施。通过综合优化,满足金融行业的严苛要求。
64 1