Java中主线程如何捕获子线程抛出的异常
首先明确线程代码的边界。其实很简单,Runnable接口的run方法所界定的边界就可以看作是线程代码的边界。Runnable接口中run方法原型如下:
public void run();
而所有的具体线程都实现这个方法,所以这里就明确了一点,线程代码不能抛出任何checked异常。所有的线程中的checked异常都只能被线程本身消化掉。:) 这样本身也是符合线程的设计理念的,线程本身就是被看作独立的执行片断,它应该对自己负责,所以由它来消化所有的checked异常是很正常的。
这样就回答了楼主的第一个问题:checked异常一定要在线程内部消化。
但是,线程代码中是可以抛出错误(Error)和运行级别异常(RuntimeException)的。Error俺们可以忽略,因为通常Error是应该留给vm的,而RuntimeException确是比较正常的,如果在运行过程中满足了某种条件导致线程必须中断,可以选择使用抛出运行级别异常来处理,如下:
public void run() {
if (...) throw new RuntimeException();
}
当线程代码抛出运行级别异常之后,线程会中断。:)这点java中解释得很清楚:
@see Thread
All threads that are not daemon threads have died, either by returning from the call to the run method or “by throwing an exception that propagates beyond the run method”.
但是对于invoke此线程的主线程会产生什么影响呢?主线程不受这个影响,不会处理这个RuntimeException,而且根本不能catch到这个异常。会继续执行自己的代码 :)
所以得到结论:线程方法的异常只能自己来处理。
但是,给某个thread设置一个UncaughtExceptionHandler,可以确保在该线程出现异常时能通过回调UncaughtExceptionHandler接口的public void uncaughtException(Thread t, Throwable e) 方法来处理异常,这样的好处或者说目的是可以在线程代码边界之外(Thread的run()方法之外),有一个地方能处理未捕获异常。但是要特别明确的是:虽然是在回调方法中处理异常,但这个回调方法在执行时依然还在抛出异常的这个线程中!另外还要特别说明一点:如果线程是通过线程池创建,线程异常发生时UncaughtExceptionHandler接口不一定会立即回调。代码示例如下:
package study20170103;
/**
* Created by apple on 17/1/3.
*/
public class ThreadTest extends ThreadGroup{
private ThreadTest(){
super("ThreadTest");
}
public static void main(String[] args) {
new Thread(new ThreadTest(),new Runnable() {//传入继承ThreadGroup的类对象
@Override
public void run() {
throw new NullPointerException();//只能抛出unchecked异常
}
}).start();
}
public void uncaughtException(Thread thread, Throwable exception)
{
/**
* 当线程抛出unckecked异常时,系统会自动调用该函数,但是是在抛出异常的线程内执行
*/
System.out.println(thread.getId());
exception.printStackTrace();//example, print stack trace
}
}
比之上述方法,还有一种编程上的处理方式可以借鉴,即,有时候主线程的调用方可能只是想知道子线程执行过程中发生过哪些异常,而不一定会处理或是立即处理,那么发起子线程的方法可以把子线程抛出的异常实例收集起来作为一个Exception的List返回给调用方,由调用方来根据异常情况决定如何应对。不过要特别注意的是,此时子线程早以终结。
线程设计的理念:“线程的问题应该线程自己本身来解决,而不要委托到外部。”
Java中主线程如何捕获子线程抛出的异常的更多相关文章
- c/c++中主线程退出,子线程也会退出
#include <windows.h> #include <process.h> /* _beginthread, _endthread */ #include <io ...
- java主线程结束和子线程结束之间的关系
(一)Main线程是个非守护线程,不能设置成守护线程. 这是因为,main线程是由java虚拟机在启动的时候创建的.main方法开始执行的时候,主线程已经创建好并在运行了.对于运行中的线程,调用Thr ...
- [Java][Android] 多线程同步-主线程等待全部子线程完毕案例
有时候我们会遇到这种问题:做一个大的事情能够被分解为做一系列相似的小的事情,而小的事情无非就是參数上有可能不同样而已! 此时,假设不使用线程,我们势必会浪费许多的时间来完毕整个大的事情.而使用线程的话 ...
- Java主线程如何等待子线程执行结束(转)
工作中往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了. 一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响主线 ...
- .Net主线程扑捉子线程中的异常
首先看一段C#代码:运行后发现主线程通过try{}catch{}是不能扑捉子线程中的抛出来的异常. 代码 ); } public void run() { ...
- python主线程捕获子线程异常
python内置threading.Thread类创建的子线程抛出的异常无法在主线程捕获,可以对该类进行优化,为子线程添加exit code属性,主线程通过获取子线程的返回状态,来判断子线程中是否发生 ...
- java 检查抛出的异常是否是要捕获的检查性异常或运行时异常或错误
/** * Return whether the given throwable is a checked exception: * that is, neither a RuntimeExcepti ...
- java主线程捕获子线程中的异常
本文主要参考:<think in java> 好,下面上货. 正常情况下,如果不做特殊的处理,在主线程中是不能够捕获到子线程中的异常的. 例如下面的情况. package com.xuey ...
- Java多线程--让主线程等待所有子线程执行完毕
数据量很大百万条记录,因此考虑到要用多线程并发执行,在写的过程中又遇到问题,我想统计所有子进程执行完毕总共的耗时,在第一个子进程创建前记录当前时间用System.currentTimeMillis() ...
随机推荐
- [leetcode-783-Minimum Distance Between BST Nodes]
Given a Binary Search Tree (BST) with the root node root, return the minimum difference between the ...
- httpd 2.2.15 添加流媒体模块
项目中使用的一直都是 httpd 2.2.15 用于播放视频资源,近期有个新产品上线发现快进视频会出现卡顿情况,因此添加了流媒体模块.(怀疑是新产品中的播放器进行了更改) 原文:http://li ...
- 《梦断代码Dreaming In Code》阅读笔记(三)
最后这几章感觉上更多是从软件完成整体上来讲的.比如说技术.方法等. 在我看来,其实一个团队一直坚持一种好的.先进的方法是不可少的.如果一个优秀的团队刚愎自用,只随着成员们喜好发展,那不能长久.比如说, ...
- C# 正则表达式 最全的验证类
///<summary> ///验证输入的数据是不是正整数 ///</summary> ///<param name="str">传入字符串&l ...
- C# 压缩组件介绍与入门
1.前言 作为吉日嘎拉权限管理系统最早的一批学习版用户,学了不少东西,在群里面也结识了很多朋友,更重要的是闲余时间,大家都发布很多可靠的外包工作.这次也是由于吉日嘎拉发布了一个有关“压缩文件损坏检测” ...
- WPF 进度条ProgressBar
今天研究了一下wpf的进度条ProgressBar 1.传统ProgressBar WPF进度条ProgressBar 这个控件,如果直接写到循环里,会死掉,界面会卡死,不会有进度.需要把进度条放到单 ...
- 转:Simple Introduction to Dirichlet Process
来源:http://hi.baidu.com/vyfrcemnsnbgxyd/item/2f10ecc3fc35597dced4f88b Dirichlet Process(DP)是一个很重要的统计模 ...
- CF757G Can Bash Save the Day?
CF757G Can Bash Save the Day? #include<bits/stdc++.h> #define RG register #define IL inline #d ...
- [洛谷P3793]由乃救爷爷
题目大意:有$n(n\leqslant2\times10^7)$个数,$m(m\leqslant2\times10^7)$个询问,每次询问问区间$[l,r]$中的最大值.保证数据随机 题解:分块,处理 ...
- [洛谷P3224][HNOI2012]永无乡
题目大意:给你$n$个点,每个点有权值$k$,现有两种操作: 1. $B\;x\;y:$将$x,y$所在联通块合并2. $Q\;x\;k:$查询第$x$个点所在联通块权值第$k$小是哪个数 题解:线段 ...