源代码分析为什么ThreadPoolExecutor的submit方法不会把运行时异常不会交给UncaughtExceptionHandler处理
版本:jdk1.6
submit在父类AbstractExecutorService中,所以分析AbstractExecutorService
AbstractExecutorService
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
分析 RunnableFuture<T> ftask = newTaskFor(task, result);
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
public FutureTask(Runnable runnable, V result) {
sync = new Sync(Executors.callable(runnable, result));
}
Executors.callable(runnable, result)
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
RunnableAdapter<T>(task, result);
public T call() {
task.run();
return result;
}
分析结果 :Executors.callable没有对run的运行异常处理
|
继续分析 FutureTask.run(),注意callable
sync.innerRun();
sync. innerRun
void innerRun() {
if (!compareAndSetState(0, RUNNING))
return;
try {
runner = Thread.currentThread();
if (getState() == RUNNING) // recheck after setting thread
innerSet(callable.call());
else
releaseShared(0); // cancel
} catch (Throwable ex) {
innerSetException(ex);
}
}
这里通过Throwable可以捕捉运行时异常,分析 innerSetException(ex);
void innerSetException(Throwable t) {
for (;;) {
int s = getState();
if (s == RAN)
return;
if (s == CANCELLED) {
// aggressively release to set runner to null,
// in case we are racing with a cancel request
// that will try to interrupt runner
releaseShared(0);
return;
}
if (compareAndSetState(s, RAN)) {
exception = t;
result = null;
releaseShared(0);
done();
return;
}
}
}
这里没有把t再抛出
所以用submit提交的任务,万一抛出运行时异常,也被程序处理了,不会抛给jvm了,所以不会交给UncaughtExceptionHandler处理
那么,如何处理任务抛出运行时异常后,需要一些资源关闭、异常日志记录等问题呢,只能用重写afterExecute(Runnable r ,Throwable ex) 方法了
总结:使用submit提交任务时 ,会把原始任务包裹成FutureTask,FutureTask中的run方法捕捉到了运行时异常处理并没有再抛出
相关推荐
教程中的源代码应该包含各种示例,比如如何创建和启动线程,如何在多线程环境中捕获和处理异常,以及如何使用线程池进行任务调度。通过这些实例,你可以深入理解多线程异常处理的实践应用。 总结,理解和掌握Java多...
这些源代码示例为开发者提供了丰富的实践机会,通过对这些代码的学习和调试,可以加深对Java编程的理解,提升编程技能,并为实际项目开发打下坚实基础。在使用过程中,结合Java官方文档和其他教程,将有助于更全面地...
线程池ThreadPoolExecutor实战及其原理分析(下)线程池ThreadPoolExecutor实战及其原理分析(下)线程池ThreadPoolExecutor实战及其原理分析(下)线程池ThreadPoolExecutor实战及其原理分析(下)线程池ThreadPoolExecutor...
在上面的三个方法中,submit(Callable<T> task) 能获取到它的返回值,submit(Runnable task, T result) 能通过传入的载体 result 间接获得线程的返回值或者准确来说交给线程处理一下,而最后一个方法 submit...
Java面试是评估程序员技术能力的重要环节,而Java面试常见笔试题常常涉及到语言基础、数据结构...源代码的练习和分析是加深理解的最佳途径,因此这个"java面试常见笔试题(源代码)"资源非常有价值,值得反复研究和练习。
5. **Java源代码分析**:源代码可能会包含对上述概念的实现,如定义进程类(包含优先级、执行时间等属性),创建进程队列,实现调度算法(如优先级比较、时间片分配等),以及模拟CPU的切换过程。此外,可能还会有...
* 数据处理:ThreadPoolExecutor 可以用于数据处理中,处理大量的数据处理任务。 * Android 应用:ThreadPoolExecutor 可以用于 Android 应用中,处理大量的后台任务。 ThreadPoolExecutor 是 Java 中一个非常重要...
**Apache Tomcat 8源代码解析** Apache Tomcat是一款开源的Java Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范,是许多Web应用开发者的重要工具。Tomcat 8是其发展的一个重要版本,引入了许多新...
《JDK之ThreadPoolExecutor源码分析1》 在Java编程中,线程池是一种高效的管理线程的方式,它通过复用已存在的线程来避免频繁创建和销毁线程带来的开销。ThreadPoolExecutor作为Java中的线程池实现,其内部机制相当...
《ThreadPoolExecutor源码解析》 ThreadPoolExecutor是Java并发编程中重要的组件,它是ExecutorService接口的实现,用于管理和调度线程的执行。理解其源码有助于我们更好地控制并发环境下的任务执行,提高系统的...
通过分析和学习这些源代码,开发者可以了解网络通信协议、多线程编程、用户界面设计等多个关键领域。 首先,我们需要理解Java的基础,包括类、对象、接口、继承、封装和多态等核心概念。在构建ICQ系统时,每个功能...
在多线程程序中,正确处理异常和中断至关重要,以保证程序的健壮性。 10. **线程优先级**:Java中的`Thread.setPriority()`方法可以设置线程优先级,但实际效果受JVM调度策略影响,不应过度依赖此机制来控制线程...
请确保按照说明正确解压文件,然后仔细阅读和分析源代码,理解每个类和方法的作用,以及它们如何协同工作来创建和管理线程。 在实践中,学习线程不仅包括创建和启动线程,还包括线程同步、线程通信(如`wait()`, `...
8. **中断与异常处理**:线程可以通过`interrupt()`方法请求中断,源代码会展示如何检查并响应中断状态。同时,线程间的异常处理也是重要的学习点,源代码可能会包含异常传递和处理的实例。 9. **线程安全的数据...
- 运行时数据区:包括堆、方法区、虚拟机栈、本地方法栈和程序计数器等各个区域的作用和管理策略。 - 字节码执行引擎:解析和执行字节码的过程,如操作数栈、本地变量表等。 2. **垃圾收集与内存管理**: - 垃圾...
- 异常类层次:了解Exception类和Error类的区别,以及如何使用try-catch-finally语句块处理异常。 - 自定义异常:学习如何创建自己的异常类,以便更好地表示特定错误情况。 4. **多线程** - 线程的创建:通过...
当线程运行时抛出未捕获的异常,线程会终止。可通过`Thread.UncaughtExceptionHandler`接口定义线程的未捕获异常处理器。 以上内容涵盖了Java多线程的基础知识点,通过实践这些源代码,开发者可以更好地理解和应用...