如下: [java] view plain copy package com.exception; import java.lang.Thread.UncaughtExceptionHandler ExceptionHandler()); thread.start(); } } class ExceptionHandler implements UncaughtExceptionHandler ,通过调用Thread.setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)方法,这是Thread的一个static 如下: [java] view plain copy package com.exception; import java.lang.Thread.UncaughtExceptionHandler Thread(new Task()); thread.start(); } } class ExceptionHandler implements UncaughtExceptionHandler
拓展 UncaughtExceptionHandler 在虚拟机中,当一个线程没有显式处理(即try catch)异常而抛出时,会将该异常事件报告给该线程对象的java.lang.Thread.UncaughtExceptionHandler 进行处理,如果线程没有设置UncaughtExceptionHandler,则默认会把异常栈信息输出到终端而使程序直接崩溃。 所以如果想在线程意外崩溃时做一些处理就可以通过实现UncaughtExceptionHandler来满足需求。 * 如果一个线程没有明确设置其 UncaughtExceptionHandler,则将其 ThreadGroup 对象作为其handler,如果 ThreadGroup 对象对异常没有什么特殊的要求,则 terminates return null; } else { UncaughtExceptionHandler ueh = uncaughtExceptionHandler
如果某一线程没有明确设置其 UncaughtExceptionHandler,则将它的 ThreadGroup 对象作为其 UncaughtExceptionHandler。 如果一个线程没有明确设置一个UncaughtExceptionHandler,那么ThreadGroup对象将会代替UncaughtExceptionHandler完成该行为。 - uncaughtExceptionHandler:为单个线程设置一个属于线程自己的uncaughtExceptionHandler,辖范围比较小。 没有设置uncaughtExceptionHandler怎么办?如果没有设置uncaughtExceptionHandler,将使用线程所在的线程组来处理这个未捕获异常。 如果没有显式设置线程的 UncaughtExceptionHandler,那么会将其 ThreadGroup 对象会作为 UncaughtExceptionHandler。
序 本文主要简述下如何设置TaskExecutor的Thread.UncaughtExceptionHandler。 配置Thread.UncaughtExceptionHandler spring默认会给async的线程池配SimpleAsyncUncaughtExceptionHandler,具体见spring-context /annotation/AsyncAnnotationAdvisor.java 不过自己配置的taskExecutor就没有这个福利了,需要自己配置,如下: final Thread.UncaughtExceptionHandler uncaughtExceptionHandler = new Thread.UncaughtExceptionHandler() { @Override threadFactoryBuilder.setNameFormat("demo-%d"); threadFactoryBuilder.setUncaughtExceptionHandler(uncaughtExceptionHandler
getUncaughtExceptionHandler() { //可以看到当 uncaughtExceptionHandler 没有赋值的时候,会返回 ThreadGroup 对象 return uncaughtExceptionHandler ! uncaughtExceptionHandler : group; } 看上述代码,如果 App 中并没有设置 uncaughtExceptionHandler 对象,那么会执行 ThreadGroup () { //可以看到当uncaughtExceptionHandler没有赋值的时候,会返回ThreadGroup对象 return uncaughtExceptionHandler uncaughtExceptionHandler : group; } 只有在我们没有设置 UncaughtExceptionHandler 的时候,才会调用 defaultUncaughtExceptionHandler
JDK5.0之前,不能为单独的Thread设置UncaughtExceptionHandler,也不能指定一个默认的UncaughtExceptionHandler。 为了可以设置一个UncaughtExceptionHandler,需要去继承ThreadGroup并覆写uncaughtException方法。 当然你也可以为所有Thread设置一个默认的UncaughtExceptionHandler,通过调用Thread.setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler 但是,如果这个单个线程是ThreadGroup中的一个Thread,那么这个线程将使用ThreadGroup的UncaughtExceptionHandler。 ThreadGroup自身已经实现了Thread.UncaughtExceptionHandler接口。
as its UncaughtExceptionHandler. uncaughtExceptionHandler : group; } // 设置未捕获异常 public void setUncaughtExceptionHandler(UncaughtExceptionHandler () { return uncaughtExceptionHandler ! uncaughtExceptionHandler : group; } 假如程序员没有调用方法Thread.setUncaughtExceptionHandler来设置uncaughtExceptionHandler public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) { checkAccess(); uncaughtExceptionHandler
,如果线程没有设置 UncaughtExceptionHandler,则默认会把异常栈信息输出到终端而使程序直接崩溃。 所以如果我们想在线程意外崩溃时做一些处理就可以通过实现 UncaughtExceptionHandler 来满足需求。 我们使用线程池设置ThreadFactory时可以指定UncaughtExceptionHandler,这样就可以捕获到子线程抛出的异常了。 UncaughtExceptionHandler 解析 我们来看下Thread中的内部接口UncaughtExceptionHandler: public class Thread { .... */ public UncaughtExceptionHandler getUncaughtExceptionHandler() { return uncaughtExceptionHandler
前言 UncaughtExceptionHandler 实现自己的UncaughtExceptionHandler 遇到的问题 结尾 前言 作为一个android开发,经常遇到crash ---- UncaughtExceptionHandler 幸运的是:安卓已经帮我们想好了解决问题的接口(UncaughtExceptionHandler)。 看一下UncaughtExceptionHandler的源码: public interface UncaughtExceptionHandler { /** * Method invoked = null) { parent.uncaughtException(t, e); } else { Thread.UncaughtExceptionHandler 从上面的源码分析我们知道,只要我们重写一个类实现UncaughtExceptionHandler接口,替换当前线程的默认UncaughtExceptionHandler对象就行。
Jdk中使用UncaughtExceptionHandler接口实现了对线程的异常信息的监控和处理 其中有一个uncaughtException(Thread a, Throwable e)方法,在这里我们可以将线程抛出的异常信息记录到日志中 handle = null; ThreadA a = null; a = new ThreadA(); //创建线程对象 handle = new ErrHandler(); //创建UncaughtExceptionHandler a.setUncaughtExceptionHandler((UncaughtExceptionHandler) handle); a.start(); //启动 } } /** * 自定义的一个UncaughtExceptionHandler */class ErrHandler implements UncaughtExceptionHandler { /** * 这里可以做任何针对异常的处理 + e.getMessage()); //开启一个另外的线程提供服务 System.out.println("现在执行另外一个替代线程提供服务......"); }} /** * 拥有UncaughtExceptionHandler
JVM会调用dispatchUncaughtException方法来寻找异常处理器(UncaughtExceptionHandler),处理异常。 getUncaughtExceptionHandler() { return uncaughtExceptionHandler ! uncaughtExceptionHandler : group; } UncaughtExceptionHandler必须显示的设置,否则默认为null。 ThreadGroup自身就是一个handler,查看ThreadGroup的源码就可以发现,ThreadGroup实现了Thread.UncaughtExceptionHandler接口,并实现了默认的处理方法 而在线程池中,该如何批量的为所有线程设置UncaughtExceptionHandler呢?我们知道,线程池中的线程是由线程工厂创建的。
03.崩溃处理入口 3.1 Java处理异常入口 UncaughtExceptionHandler接口,官方介绍为:@FunctionalInterface public interface UncaughtExceptionHandler as its UncaughtExceptionHandler. 如果一个线程没有明确设置一个UncaughtExceptionHandler,那么ThreadGroup对象将会代替UncaughtExceptionHandler完成该行为。 private volatile UncaughtExceptionHandler uncaughtExceptionHandler; private static volatile UncaughtExceptionHandler public class ThreadHandler implements Thread.UncaughtExceptionHandler { private Thread.UncaughtExceptionHandler
问题来了,我们的代码中异常不可能全部捕获 如果要捕获那些没被业务代码捕获的异常,可以设置Thread类的uncaughtExceptionHandler属性。 捕获到:customThread 0发生异常/ by zero 线程customThread 1执行 UncaughtExceptionHandler捕获到:customThread 1发生异常/ by zero 线程customThread 2执行 UncaughtExceptionHandler捕获到:customThread 2发生异常/ by zero 线程customThread 3执行 UncaughtExceptionHandler 捕获到:customThread 3发生异常/ by zero 线程customThread 4执行 UncaughtExceptionHandler捕获到:customThread 4发生异常/ by 所以通过UncaughtExceptionHandler想将异常吞掉使线程复用这招貌似行不通。 它只是做了一层异常的保底处理。
* @since 1.5 * @return the uncaught exception handler for this thread */ public UncaughtExceptionHandler getUncaughtExceptionHandler() { return uncaughtExceptionHandler ! uncaughtExceptionHandler : group; } 如果当前线程没有设置UncaughtExceptionHandler,则由该线程所属的线程组ThreadGroup来处理 我们需要在提交的任务中自行处理异常,不再抛出此异常,并且日志输出异常堆栈,最好设置线程的UncaughtExceptionHandler 作为异常的输出兜底处理: ThreadFactory threadFactory 我们需要在提交的任务中自行处理异常,不再抛出此异常,并且日志输出异常堆栈,最好设置线程的UncaughtExceptionHandler 作为异常的输出兜底处理。
() { return uncaughtExceptionHandler ! class ThreadGroup implements Thread.UncaughtExceptionHandler {...} = null) { parent.uncaughtException(t, e); } else { Thread.UncaughtExceptionHandler 一般我们创建线程池时都会使用线程工厂, 在创建线程工厂时可以指定 UncaughtExceptionHandler 处理未捕获异常策略 @Test public void executorTest() { Thread.UncaughtExceptionHandler sceneHandler = new Thread.UncaughtExceptionHandler() {
它们不会在调用栈中逐层传递,而是默认地在控制台中输出栈追踪信息,并终止线程 我们可以通过实现java.lang.Thread.UncaughtExceptionHandler接口来获取RuntimeException 举个栗子 将异常写入日志 public class MyDemo implements java.lang.Thread.UncaughtExceptionHandler{ public log.error(Level.SEVERE, "Thread terminated with exception:" + t.getName(), e); } } 要为线程池中的所有线程设置一个UncaughtExceptionHandler 需要注意的是只有通过execute提交的任务,才能将它抛出的异常交给UncaughtExceptionHandler;而通过submit提交的任务,无论是抛出的未检查的异常还是已检查的异常,都将被认为是任务返回状态的一部分
)来保存未捕获异常的处理者 在线程需要确定Throwable分发目标的处理者时,优先获取当前线程中uncaughtExceptionHandler变量 如果出问题线程的uncaughtExceptionHandler * @since 1.5 * @return the uncaught exception handler for this thread */ public UncaughtExceptionHandler getUncaughtExceptionHandler() { return uncaughtExceptionHandler ! uncaughtExceptionHandler : group; } 如果Throwable分发给ThreadGroup ThreadGroup会尝试转给它的父ThreadGroup(如果存在的话) = null) { parent.uncaughtException(t, e); } else { Thread.UncaughtExceptionHandler
int parallelism, ForkJoinWorkerThreadFactory factory, UncaughtExceptionHandler int parallelism, ForkJoinWorkerThreadFactory factory, UncaughtExceptionHandler makeCommonPool() { int parallelism = -1; ForkJoinWorkerThreadFactory factory = null; UncaughtExceptionHandler = null) handler = ((UncaughtExceptionHandler)ClassLoader. uncaughtExceptionHandler;private boolean asyncMode = false;private int awaitTerminationSeconds = 0;@
at java.lang.Thread.run(Thread.java:745)一旦run()方法抛出异常,线程就会中止并被下列活动取代:java虚拟机(JVM)寻找Thread.UncaughtExceptionHandler 的实例,该实例有Thread的void set UncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)方法设置。 int x = 1 / 0; } }; Thread thd = new Thread(r); Thread.UncaughtExceptionHandler uceh; uceh = new Thread.UncaughtExceptionHandler() { @Override public void + t); } }; thd.setUncaughtExceptionHandler(uceh); uceh = new Thread.UncaughtExceptionHandler
在AppDelegate.m文件里,加入例如以下代码: 01 NSUncaughtExceptionHandler* _uncaughtExceptionHandler = nil; 02 void UncaughtExceptionHandler(NSException *exception) { 03 NSLog(@"CRASH: %@", exception); 04 NSLog(@"Stack didFinishLaunchingWithOptions:( NSDictionary *)launchOptions方法中加入一下代码: 1 // 保存系统处理异常的Handler 2 _uncaughtExceptionHandler = NSGetUncaughtExceptionHandler(); 3 4 // 设置处理异常的Handler 5 NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler