关于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多线程中,当两个或以上的线程对同一个数据进行操作的时候,可能会产生“竞争条件”的现象.这种现象产生的根本原因是因为多个线程在对同一个数据进行操作,此时对该数据的操作 ...
随机推荐
- RabbitMQ快速入门
最近一段项目实践中大量使用了基于RabbitMQ的消息中间件,也积累的一些经验和思考,特此成文,望大家不吝赐教. 本文包括RabbitMQ基本概念.进阶概念.实践与思考等三部分,着重强调相关概念和基于 ...
- Java中位运算符的使用
先预知识: 数据在计算机中是以二进制的形式进行存储的,而二进制在内存中是以补码的形式进行存储的.在介绍位运算之前,首先来看一下原码.反码和补码的概念.由于正数的原码.反码和补码的形式都是一样的,所以以 ...
- ReentrantLock和condition源码浅析(一)
转载请注明出处..... 一.介绍 大家都知道,在java中如果要对一段代码做线程安全操作,都用到了锁,当然锁的实现很多,用的比较多的是sysnchronize和reentrantLock,前者是ja ...
- Xamarin Essentials教程数据处理传输数据
Xamarin Essentials教程数据处理传输数据 在移动应用程序中,除了常规的数据处理,还涉及数据存储.数据传输.版本数据多个方面.Xamarin.Essentials组件提供了多个数据处理相 ...
- Codeforces.226D.The table(构造)
题目链接 \(Description\) 给定一个\(n\times m\)的矩阵\(A_{i,j}\),每次可以将一列或一行取负.求一个方案使得若干次操作后,每行每列的和都非负. \(n,m\leq ...
- 157. [USACO Nov07] 奶牛跨栏
157. [USACO Nov07] 奶牛跨栏(点击转到COGS) 输入文件:hurdles.in 输出文件:hurdles.out 时间限制:1 s 内存限制:128 MB 译 by CmY ...
- Shell脚本笔记(七)控制Shell脚本
控制Shell脚本 一.处理信号 1) SIGHUP本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联. ...
- 2009 ACM 水题
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2009 思路:寻找平方根的函数,c++里面有sqrt,一定要注意 1 添加头文件#include <i ...
- Scrapy基础(三) ------xpath基础
xpath简介 1,使用路径表达式在xml和html中解析 2,包含标准函数路(所有库支持的xpath语法一致) 3,W3C标准 节点: <body> 第一个节点: <h ...
- java的类和对象
创建狗狗类: /** * 狗狗类 * @author Administrator * */ public class Dog { String name="无名氏"; //姓名 i ...