线程的异常处理(多线程的异常处理)

一:众所周知,当程序运行出错时,会出现异常。但是溯源到线程本身,线程是如何处理异常的呢?

二:首先我们知道,异常实际分为两种

        1.受检异常

                定义方法时,必须声明所有可能抛出的异常。在调用该方法时,必须手动捕获它的checked Exception,即受检异常。如IO异常,SQL异常等。因此:受检异常实际可以理解为需要被手动捕获的异常,实际就是编译器会主动检查的异常,如B方法中主动抛出了异常,若方法A中调用B方法,也需要手动捕获该受检异常,当没有手动捕获异常时,编译器会报错

        2.非受检异常

                非受检异常,实际就是RuntimeException运行时异常(编译器不会主动检查的异常),在定义方法时是不需要声明的,如空指针异常。在调用该方法时也不需要手动捕获该异常,也就是说,非受检异常也可以理解为未捕获的异常,运行过程中如果发生了此类异常,会被直接抛给jvm,由jvm来处理该异常

三:当我们了解了异常后,就可以进一步了解线程异常了

        1.线程设计的理念是自己线程内部的异常由自己线程内部来处理,因此假设在main主线程中创建了一个子线程,如果子线程出现了异常,main主线程是无法感知和catch到的(即使子线程出现了异常,父线程不会有任何影响,依然会正常运行)

        2.如何捕获子线程中的异常

        (1)直接在可执行对象的run方法中使用try-catch语句捕获

        (2)通过设置线程的异常回调接口UncaughtExceptionHandler实际处理该线程异常的仍然是该子线程,只是通过回调接口,把处理异常的方法从具体的可执行对象本身的run方法中抽离了出去,使用这种方法,可以监控哪个子线程发生了异常,因为每一个线程发生异常都会回调该接口)

        3.UncaughtExceptionHandler回调接口说明

        (1)当线程运行过程中出现异常时,JVM会调用Thread类的dispatchUncaughtException方法,该方法会调用getUncaughtExceptionHandler().uncaughtException(this,e)来处理异常

        (2)getUncaughtExceptionHandler()方法中,若当前线程的uncaughtExceptionHandler不为空,则使用当前线程的uncaughtExceptionHandler,否则使用线程组的uncaughtExceptionHandler

        (3)因此,如果想要获得线程的运行时异常,就需要设置当前线程的uncaughtExceptionHandler实例,并实现该回调接口的uncaughtException(this,e)方法

        4.在Thread类中有关处理异常的方法有:

                (1)getDefaultUncaughtExceptionHandler():获取全局(默认)的UncaughtExceptionHandler

                (2)setDefalutUncaughtException():设置默认的UncaughtExceptionHandler

                (3)getUncaughtExceptionHandler():获取当前线程的UncaughtExceptionHandler

                (4)setUncaughtExceptionHandler():设置当前线程的UncaughtExceptionHandler

四:总结

        如果线程运行中产生了异常,首先会生成一个异常对象。我们平时throw抛出异常,就是把异常交给jvm处理。jvm首先会去找有没有能够处理该异常的处理者(首先找到当前抛出异常的调用者,如果当前调用者无法处理,则会沿着方法调用栈一路找下去),能够处理的调用者实际就是看方法的catch关键字,jvm会把该异常对象封装到catch入参,允许开发者手动处理异常。若找不到能够处理的处理者(实际就是没有手动catch异常,比如未受检异常),就会交该线程处理;JVM会调用Thread类的dispatchUncaughtException()方法,该方法调用了getUncaughtExceptionHandler(),uncaughtExceptoin(this,e)来处理了异常,如果当前线程设置了自己的UncaughtExceptionHandler,则使用该handler,调用自己的uncaughtException方法,如果没有,则使用当前线程所在的线程组的Handler的uncaughtExceptoin()方法,如果线程中中也没有设置,则直接把异常定向到System.err中,打印异常信息(控制台红色字体输出的异常就是被定向到System.err的异常)

最后:附上后端技术交流圈 ff1341658,欢迎各位大佬入圈交流.......(先添加好友后拉群,添加好友时请备注:小白不黑)

你可能感兴趣的:(java,开发语言,后端,异常Exception)