网站建设 事业单位 安全,怎么给网站做aap,哈尔滨网络建站的公司,如何申请个人企业邮箱提示#xff1a;文章写完后#xff0c;目录可以自动生成#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、UncaughtExceptionHandler 是什么#xff1f;二、使用步骤1.通过try-catch捕捉子线程的问题2.非线程池设置3.线程池的情况下设置UncaughtExceptionHandler… 提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档 文章目录 前言一、UncaughtExceptionHandler 是什么二、使用步骤1.通过try-catch捕捉子线程的问题2.非线程池设置3.线程池的情况下设置UncaughtExceptionHandler 总结 前言
前些天在网上逛论坛的时候看到 UncaughtExceptionHandler 貌似从来没用过所以学习下 一、UncaughtExceptionHandler 是什么
/*** 当线程由于未捕获异常而突然终止时调用的处理程序接口。 * 当线程由于未捕获异常即将终止时Java虚拟机将使用getUncaughtExceptionHandler查询线程的* UncaughtExceptionHandler并调用处理程序的uncaughtException方法将线程和异常作为参数传递。* 如果线程未显式设置其UncaughtExceptionHandler则其ThreadGroup对象将充当其* UncaughtExceptionHandler。* 如果ThreadGroup对象对处理异常没有特殊要求它可以将调用转发给默认的未捕获异常处理程序。*/
public interface UncaughtExceptionHandler {/*** 方法该方法在给定线程由于给定的未捕获异常而终止时调用。 * Java虚拟机将忽略此方法引发的任何异常。 * 参数 * t–线程 * e–异常*/void uncaughtException(Thread t, Throwable e);}
这个描述看取来 就是给程序员一个钩子函数让程序可以感知到线程非正常关闭时的情况可以打日志 或者 啥操作
二、使用步骤
1.通过try-catch捕捉子线程的问题
public class Test {public static void main(String[] args) {try {Thread thread new Thread(new Task());thread.start();} catch (Exception e) {System.out.println(Exception: e.getMessage());}}
}class Task implements Runnable {Overridepublic void run() {System.out.println(1 / 0);}
}
输出
Exception in thread Thread-0 java.lang.ArithmeticException: / by zeroat com.example.demo.config.Task.run(ttt.java:33)at java.lang.Thread.run(Thread.java:745)
可以看到其实catch 并未捕捉到 异常而子线程的错误 抛出到虚拟机了
2.非线程池设置
通过设置线程的UncaughtExceptionHandler 则可以捕捉到异常
public class Test {public static void main(String args[]) {Thread thread new Thread(new Task());thread.setUncaughtExceptionHandler(new ExceptionHandlerDemo());thread.start();}
}class ExceptionHandlerDemo implements Thread.UncaughtExceptionHandler {Overridepublic void uncaughtException(Thread t, Throwable e) {System.out.println(whp Exception: e.getMessage());}
}class Task implements Runnable {Overridepublic void run() {System.out.println(1 / 0);}
}输出
whp Exception: / by zero3.线程池的情况下设置UncaughtExceptionHandler
public class testClass {public static void main(String[] args) throws ExecutionException, InterruptedException {ThreadPoolTaskExecutor executorService buildThreadPoolTaskExecutor();//这里注意先是execute ,如果是submit 则有些不同 需要get 才能出现错误executorService.execute(() - run(execute方法));}private static void run(String name) {String printStr 【thread-name: Thread.currentThread().getName() ,执行方式: name】;System.out.println(printStr);throw new RuntimeException(printStr ,出现异常);}private static ThreadPoolTaskExecutor buildThreadPoolTaskExecutor() {ThreadPoolTaskExecutor executorService new ThreadPoolTaskExecutor();executorService.setCorePoolSize(5);executorService.setMaxPoolSize(5);executorService.setQueueCapacity(10);executorService.setKeepAliveSeconds(10);executorService.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executorService.setThreadFactory(new DefineThreadFactory(小王));executorService.initialize();return executorService;}}import io.netty.util.concurrent.DefaultThreadFactory;/*** 这里图简单 继承了一个ThreadFactory实现*/
public class DefineThreadFactory extends DefaultThreadFactory {public DefineThreadFactory(String poolName) {super(poolName);}Overridepublic Thread newThread(Runnable r) {Thread t super.newThread(r);//给生成的线程设置一个错误处理器t.setUncaughtExceptionHandler(new ExceptionHandler());return t;}
}public class ExceptionHandler implements Thread.UncaughtExceptionHandler {Overridepublic void uncaughtException(Thread t, Throwable e) {System.out.println(defineException: e.getMessage());}
}
输出
09:55:09.844 [main] INFO org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - Initializing ExecutorService
【thread-name:小王-1-1,执行方式:execute方法】
defineException: 【thread-name:小王-1-1,执行方式:execute方法】,出现异常
可以看到 线程池中工作线程 的错误也被捕捉到了 总结
UncaughtExceptionHandler API 提供了一个优雅的方式让我们可以处理线程的异常错误。