type
status
date
slug
summary
tags
category
icon
password
example-row
example-row
当单线程的程序发生一个未捕获的异常时我们可以采用
try....catch
进行异常的捕获,但是在多线程环境中,线程抛出的异常是不能用try....catch
捕获的,这样就有可能导致一些问题的出现,比如异常的时候无法回收一些系统资源,或者没有关闭当前的连接等等。普通try....catch
运行结果:
可以看到在多线程中通过
try....catch
试图捕获线程的异常是不可取的。Thread
的run
方法是不抛出任何检查型异常的,但是它自身却可能因为一个异常而被中止,导致这个线程的终结。主动处理多线程中未捕获异常
如果任务抛出了一个未检查异常,那么它将使线程终结,但会首先通知框架该现场已经终结。然后框架可能会用新的线程来代替这个工作线程,也可能不会,因为线程池正在关闭,或者当前已有足够多的线程能满足需要。当编写一个向线程池提交任务的工作者类线程类时,或者调用不可信的外部代码时(例如动态加载的插件),使用这些方法中的某一种可以避免某个编写得糟糕的任务或插件不会影响调用它的整个线程。
运行结果:
使用UncaughtExceptionHandle
处理多线程中未捕获异常
在
Thread API
中同样提供了UncaughtExceptionHandle
,它能检测出某个由于未捕获的异常而终结的情况。这两种方法是互补的,通过将二者结合在一起,就能有效地防止线程泄露问题。设置默认UncaughtExceptionHandler
处理多线程中未捕获异常
可以为所有的
Thread
设置一个默认的UncaughtExceptionHandler
,通过调用Thread.setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
方法,这是Thread
的一个static
方法。
运行结果:
线程池excuse
方法中处理多线程中未捕获异常
如果换成线程池执行
execute
的方法发生异常ExceptionHandler
同上面例子,运行结果:可以看到并未捕获到异常。可以通过将异常的捕获封装到
Runnable
或者Callable
来处理多线程中未捕获异常:运行结果:
线程池submit
方法中处理多线程中未捕获异常
只有通过
execute
提交的任务,才能将它抛出的异常交给UncaughtExceptionHandler
,而通过submit
提交的任务,无论是抛出的未检测异常还是已检查异常,都将被认为是任务返回状态的一部分。如果一个由submit
提交的任务由于抛出了异常而结束,那么这个异常将被Future.get
封装在ExecutionException
中重新抛出。例子1:
例子2:
例子1和例子2运行结果都是:
submit
方法下,捕获异常的处理方式如下:运行结果:
参考
- 作者:黄x黄
- 链接:https://hxhowl.site/article/javanote010-UncaughtExceptionHandler
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章