高并发与多线程网络学习笔记(七):如何给你的应用程序注入钩子及如何捕获线程运行期间的异常

1.如何获得线程的异常

public class ExitCapture {
    public static void main(String[] args) {
        //java中的Runtime可以调用shell脚本和.exe文件
        //在程序运行结束时得到一个钩子,当程序抛出异常时并不会立即结束。
        Runtime.getRuntime().addShutdownHook(new Thread(()->{
            System.out.println("The application will be exit.");
            notifyAndrelease();
        }));//关闭时得到一个钩子
        int i=0;
        while(true){

            try {
                Thread.sleep(1000);
                System.out.println("I am working.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            i++;
            if(i>20)
                throw new RuntimeException("error");
        }

    }
private  static  void notifyAndrelease(){

        System.out.println("notify to the admain");
        try{
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
         System.out.println("will release resource");
    try{
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("will release down!!");

    }
}

利用钩子程序可以防止程序出现异常时可以利用钩子程序释放资源(数据库连接、网络连接),这样可以避免当程序异常终止时由操作系统释放资源造成系统资源紧张。

线程中的run()方法是不允许抛出异常的,只能在线程中捕获异常并将异常打印到控制台/log,但是无法将异常告诉前端。

类似于以下程序:

public class ThreadException {

    private final static int A=10;
    private final static int B=0;

    public static void main(String[] args) {
     Thread t=new Thread(()->{

         try {
             Thread.sleep(5000);
             int result=A/B;
             System.out.println(result);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
     });
     t.start();
    }
}

运行结果:
只能打印到控制台,但是不能将线程抛出的异常获取(catch)到

Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
	at com.learn.thread.ThreadException.lambda$main$0(ThreadException.java:13)
	at java.lang.Thread.run(Thread.java:748)

对原程序进行改进:

public class ThreadException {

    private final static int A=10;
    private final static int B=0;

    public static void main(String[] args) {
     Thread t=new Thread(()->{

         try {
             Thread.sleep(5000);
             int result=A/B;
             System.out.println(result);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
     });
     //利用setUncaughtExceptionHandler方法获取线程未捕获的异常,并将异常打印出来。
     t.setUncaughtExceptionHandler((thread,e)->{
         System.out.println(e);
         System.out.println(thread);
     });
     t.start();
    }
}

运行结果:

java.lang.ArithmeticException: / by zero   //打印异常
Thread[Thread-0,5,main]   // Thread-0表示线程名称  5代表优先级  main代表其所在的线程组

利用getStackTrace()方法打印函数的调用关系和调用位置
在这里插入图片描述

getStackTrace()方法
在这里插入图片描述
在这里插入图片描述
运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值