-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
深度解析Java线程池的异常处理机制 #3
Comments
总结的第二种方法这样写jdk6应该不能弄吧 |
@Joker1995 如果指的是第二种线程池的方式,这里需要JDK8的lambda表达式支持.,不过没必要用这种形式,JDK1.6也OK的。 |
有理有据 |
这种方式submit依然不会被设置的setUncaughtExceptionHandler方法捕获的 而execute是可以的 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
前言
今天小伙伴遇到个小问题,线程池提交的任务如果没有catch异常,那么会抛到哪里去,之前倒是没研究过,本着实事求是的原则,看了一下代码。
正文
小问题
考虑下面这段代码,有什么区别呢?你可以猜猜会不会有异常打出呢?如果打出来的话是在哪里?:
源码解析
我们下面就来看下代码, 其实就是将我们提交过去的Runnable包装成一个Future
接下来就会实际提交到队列中交给线程池调度处理:
那么接下来看看线程池核心的流程:
submit的方式
那么我们可以这里是直接调用的run方法,先看submit的方式,我们知道最终传递过去的是一个FutureTask,也就是说会调用这里的run方法,我们看看实现:
可以看到其实类似于直接吞掉了,这样的话我们调用get()方法的时候会拿到, 比如我们可以重写afterExecute方法,从而可以得到实际的异常:
execute的方式
那么如果是直接exeture的方式有啥不同呢?这样的话传递过去的就直接是Runnable,因此就会直接抛出:
那么这里的异常到底会抛出到哪里呢, 我们看看JVM具体是怎么处理的:
可以看到这里最终会去调用Thread#dispatchUncaughtException方法:
这里如果环境是tomcat的话最终会打到catalina.out:
总结
对于线程池、包括线程的异常处理推荐一下方式:
1 直接try/catch,个人 基本都是用这种方式
2 线程直接重写整个方法:
3 也可以直接重写
protected void afterExecute(Runnable r, Throwable t) { }
方法The text was updated successfully, but these errors were encountered: