在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多线程中异常捕获的理解的更多相关文章

  1. 转载:Java多线程中join方法的理解

    转载自:http://uule.iteye.com/blog/1101994 thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A ...

  2. Java多线程中join方法的理解

    thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B. t.join( ...

  3. Java多线程中的常用方法

    本文将带你讲诉Java多线程中的常用方法   Java多线程中的常用方法有如下几个 start,run,sleep,wait,notify,notifyAll,join,isAlive,current ...

  4. Java正则表达式中的捕获组的概念及相关API使用

    要弄清这三个方法,首先要弄清Java正则表达式中的捕获组的概念.捕获组也就是Pattern中以括号对“()”分割出的子Pattern.至于为什么要用捕获组呢,主要是为了能找出在一次匹配中你更关心的部分 ...

  5. java多线程中的三种特性

    java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...

  6. java 多线程中的wait方法的详解

    java多线程中的实现方式存在两种: 方式一:使用继承方式 例如: PersonTest extends Thread{ String name; public PersonTest(String n ...

  7. java多线程中并发集合和同步集合有哪些?区别是什么?

    java多线程中并发集合和同步集合有哪些? hashmap 是非同步的,故在多线程中是线程不安全的,不过也可以使用 同步类来进行包装: 包装类Collections.synchronizedMap() ...

  8. java多线程中最佳的实践方案是什么?

    java多线程中最佳的实践方案是什么? 给你的线程起个有意义的名字.这样可以方便找bug或追踪.OrderProcessor, QuoteProcessor or TradeProcessor 这种名 ...

  9. Java多线程中的竞争条件、锁以及同步的概念

    竞争条件 1.竞争条件: 在java多线程中,当两个或以上的线程对同一个数据进行操作的时候,可能会产生“竞争条件”的现象.这种现象产生的根本原因是因为多个线程在对同一个数据进行操作,此时对该数据的操作 ...

随机推荐

  1. springboot整合视图层之freemarker

    整合freemarker要求必须将视图文件放在 src/main/resources下的templates文件夹下,该文件夹是安全的不可直接访问的,必须由controller之类的接受请求类去跳转,因 ...

  2. Android _立体车库界面

    <?xml version="1.0" encoding="UTF-8"?><LinearLayout    xmlns:android=&q ...

  3. 2017-9-24-Linux移植:ubuntu server 16.04无法联网&无法apt-get update解决

    无法上网!!!不能忍.. 现象:ifconfig 毛都没有,想找一下ip都找不到. ifconfig –a 可以列出所有网卡设备,确认VM VirtualBox网卡开对了,已经给到了虚拟机. 编辑/e ...

  4. Linux系统模式之间的转换

    1.默认开机进入文本模式 如果想让开机自动进纯文本模式, 修改/etc/inittab 找到其中的 id:5:initdefault: 这行指示启动时的运行级是5,也就是图形模式 改成3就是文本模式了 ...

  5. MySql中的事务、JDBC事务、事务隔离级别

    一.MySql事务 之前在Oracle中已经学习过事务了,这个东西就是这个东西,但是在MySql中用法还是有一点不同,正好再次回顾一下. 先看看MySql中的事务,默认情况下,每执行一条SQL语句,都 ...

  6. js 倒计时10s

    <button id="send">允许点击</button> var wait = 10; function time(o){ if(wait==0){ ...

  7. WebStorm中使用npm包管理器

    1.首先安装Node.js,安装之后添加NodeJs的安装路径到系统Path环境变量,在控制台之中测试node,与npm命令是否工作正常. 2.配置npm的源为国内的淘宝镜像,这里不推荐使用cnpm ...

  8. C# 计算地图上某个坐标点的是否在多边形内

    这个方法引用自群友的博客 https://www.xiaofengyu.com/?p=143 使用百度地图的时候,常常会用到判断一个点是否在一个多边形的范围内,该方法用到的是射线法, 通过修改Java ...

  9. django项目的新建相关的命令及配置

    创建工程 django-admin startproject 工程名称   运行开发服务器 python manage.py runserver   创建子应用 python manage.py st ...

  10. 从注册表清理 IE10,IE11 用户代理字符串(UserAgent)中的垃圾信息

    某一天,我发现我的 IE User Agent 字符串里面竟然含有刷机大师.百度浏览器等许多垃圾,国货流氓见怪不怪了. 微软自家的.NET CLR也占据了一大片,看着也不爽. 决定清理一下,但是却没找 ...