关于java多线程中异常捕获的理解
在java多线程程序中,所有线程都不允许抛出未捕获的checked exception(比如sleep时的InterruptedException),也就是说各个线程需要自己把自己的checked exception处理掉。
这句话怎么理解,最简单的看下图,也就是不能在Runnable的run方法上抛出异常,必须在里面捕获。

这一点是通过java.lang.Runnable.run()方法声明(因为此方法声明上没有throw exception部分)进行了约束。但是线程依然有可能抛出unchecked exception(如运行时异常),当此类异常跑抛出时,线程就会终结,而对于主线程和其他线程完全不受影响,且完全感知不到某个线程抛出的异常(也是说完全无法catch到这个异常)。JVM的这种设计源自于这样一种理念:“线程是独立执行的代码片断,线程的问题应该由线程自己来解决,而不要委托到外部。”基于这样的设计理念,在Java中,线程方法的异常(无论是checked还是unchecked exception),都应该在线程代码边界之内(run方法内)进行try catch并处理掉.换句话说,我们不能捕获从线程中逃逸的异常。
看下面的例子:
public class ExceptionTest {
public static void main(String[] args) {
try {
new Thread(new ExceptionTask()).start();
} catch (Exception e) {
System.out.println("注意看我是否能打印。。。");
e.printStackTrace();
}
}
}
class ExceptionTask implements Runnable {
@Override
public void run() {
System.out.println("".substring(0, 10));
}
}
打印结果
Exception in thread "Thread-0" java.lang.StringIndexOutOfBoundsException: String index out of range: 10
at java.lang.String.substring(Unknown Source)
at com.actuator.ExceptionTask.run(ExceptionTest.java:21)
at java.lang.Thread.run(Unknown Source)
从运行结果中,我们可以看到的是,"Thread-0"线程里的异常在main线程中没有catch到。
问题来了,我们如果需要捕获"Thread-0"线程的unchecked异常时该怎么办?Java SE5之后,我们可以通过Executor来解决这个问题。
Thread.UncaughtExceptionHandler是java SE5中的新接口,它允许我们在每一个Thread对象上添加一个异常处理器。(UncaughtExceptionHandler)。Thread.UncaughtExceptionHandler.uncaughtException()方法会在线程因未捕获的异常而面临死亡时被调用。
下面这个例子简单的演示了如何使用UncaughtExceptionHandler。
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory; public class ExceptionTest { public static void main(String[] args) { // 下面有两种方式来执行线程 // 第一种,非线程池写法
Thread t = new Thread(new ExceptionTask());
t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("线程"+t.getName()+"捕获到异常:"+e.getMessage());
}
});
t.start(); // 第二种,线程池写法
ExecutorService executorService = Executors.newCachedThreadPool(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("线程"+t.getName()+"捕获到异常:"+e.getMessage());
}
});
return t;
}
});
executorService.execute(new ExceptionTask()); } } class ExceptionTask implements Runnable { @Override
public void run() {
System.out.println("".substring(0, 10));
} }
两个执行结果一样
线程Thread-0捕获到异常:String index out of range: 10
关于java多线程中异常捕获的理解的更多相关文章
- 转载:Java多线程中join方法的理解
转载自:http://uule.iteye.com/blog/1101994 thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A ...
- Java多线程中join方法的理解
thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B. t.join( ...
- Java多线程中的常用方法
本文将带你讲诉Java多线程中的常用方法 Java多线程中的常用方法有如下几个 start,run,sleep,wait,notify,notifyAll,join,isAlive,current ...
- Java正则表达式中的捕获组的概念及相关API使用
要弄清这三个方法,首先要弄清Java正则表达式中的捕获组的概念.捕获组也就是Pattern中以括号对“()”分割出的子Pattern.至于为什么要用捕获组呢,主要是为了能找出在一次匹配中你更关心的部分 ...
- java多线程中的三种特性
java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...
- java 多线程中的wait方法的详解
java多线程中的实现方式存在两种: 方式一:使用继承方式 例如: PersonTest extends Thread{ String name; public PersonTest(String n ...
- java多线程中并发集合和同步集合有哪些?区别是什么?
java多线程中并发集合和同步集合有哪些? hashmap 是非同步的,故在多线程中是线程不安全的,不过也可以使用 同步类来进行包装: 包装类Collections.synchronizedMap() ...
- java多线程中最佳的实践方案是什么?
java多线程中最佳的实践方案是什么? 给你的线程起个有意义的名字.这样可以方便找bug或追踪.OrderProcessor, QuoteProcessor or TradeProcessor 这种名 ...
- Java多线程中的竞争条件、锁以及同步的概念
竞争条件 1.竞争条件: 在java多线程中,当两个或以上的线程对同一个数据进行操作的时候,可能会产生“竞争条件”的现象.这种现象产生的根本原因是因为多个线程在对同一个数据进行操作,此时对该数据的操作 ...
随机推荐
- 从零搭建 ES 搜索服务(三)同义词搜索
一.前言 上篇介绍了 ES 的基础搜索,能满足我们基本的需求,然而在实际使用中还可能希望搜索「番茄」能将包含「西红柿」的结果也罗列出来,本篇将介绍如何实现同义词之间的搜索. 二.安装 ES 同义词插件 ...
- oracle中to_timestamp和to_date什么区别
date类型是Oracle常用的日期型变量,时间间隔是秒.两个日期型相减得到是两个时间的间隔,注意单位是“天”. timestamp是DATE类型的扩展,可以精确到小数秒(fractional_sec ...
- XamarinAndroid组件教程RecylerView自定义适配器动画
XamarinAndroid组件教程RecylerView自定义适配器动画 如果RecyclerViewAnimators.Adapters命名空间中没有所需要的适配器动画,开发者可以自定义动画.此时 ...
- [R] R dataframe 中对列使用sort或者order的注意
存在这样的需求: 针对每列的值, 对列进行排序. 这样处理过数据后, 在excel中对数据作图时, 使数据呈现有序. R中sort数据的时候, 如果数据中存在字符串, R会将数据转化为characte ...
- Android系统定制——Download Android System 及加载system镜像文件
定制android系统(配置及相关系统的镜像文件),具体可参考:Driver_All_in_One_V1.0——MT6735_6753.pdf文档,特别需要理解的是Download部分. 与之对应的软 ...
- 潭州课堂25班:Ph201805201 django 项目 第二十五课 文章多级评论前后台实现 (课堂笔记)
添加新闻评论功能 1.分析 业务处理流程: 判断前端传的新闻id是否为空,是否为整数.是否不存在 判断评论的内容是否为空 判断是否有父评论,父评论的id是否与新闻id匹配 判断用户是否登录 保存新闻评 ...
- 数模转换ADC08009应用
#include <reg52.h> //头文件 #define uchar unsigned char //宏定义无符号字符型 #define uint unsigned int //宏 ...
- HDU5293 : Tree chain problem
问题即:选择价值和最多的链,使得每个点最多被一条链覆盖. 那么考虑其对偶问题:选择最少的点(每个点可以重复选),使得每条链上选了至少$w_i$个点. 那么将链按照LCA的深度从大到小排序,每次若发现点 ...
- 线段树及Lazy-Tag
一:线段树 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点.使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(lo ...
- yii2 用 bootstrap 给元素添加背景色
使用 bootstrap 给元素添加背景色 1.bootstrap 官网:http://getbootstrap.com/ 2.bootstrap 中文官网:http://v3.bootcss.com ...