由于线程的本质特性,使得你不能捕获从线程中逃逸的异常,如:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class App { public static void main(String[] args) throws InterruptedException {
try {
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Task());
exec.shutdown();
} catch (Exception e) {
System.out.println("异常:"+e.getMessage());
}
}
} /**
* 定义任务
*
* @author Administrator
*/
class Task implements Runnable { @Override
public void run() {
throw new RuntimeException("运行时错误");
}
}

输出:

Exception in thread "pool-1-thread-1" java.lang.RuntimeException: 运行时错误
at Task.run(App.java:27)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

可以看到一旦异常逃逸出run方法,将直接传播到顶层,且捕获不了。当然你可以在run方法里处理这些异常,但如果不想再run里处理呢?

为了解决这个问题,我们需要修改Executors产生线程的方式,Thread.setUncaughtExceptionHandler是Java5的新接口,它允许你在每个Thread对象上附着一个异常处理器。Thread.setUncaughtExceptionHandler.uncaughtException()会在线程因未捕获的异常而临近死亡时被调用。这里仍然需要用到线程工厂ThreadFactory:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory; public class App { public static void main(String[] args) throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool(new MyThreadFactory());
exec.execute(new Task());
exec.shutdown();
}
} /**
* 定义任务
*
* @author Administrator
*/
class Task implements Runnable { @Override
public void run() {
throw new RuntimeException("运行时错误");
}
} /**
* 线程工厂
* @author Administrator
*
*/
class MyThreadFactory implements ThreadFactory{ @Override
public Thread newThread(Runnable r) {
Thread t=new Thread(r);
t.setUncaughtExceptionHandler(new MysetUncaughtExceptionHandler());
return t;
}
} /**
* 异常处理器
* @author Administrator
*
*/
class MysetUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{ @Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("异常:"+e.getMessage());
}
}

输出:

异常:运行时错误

其实在实际应用中根据定制,ThreadFactory是经常用到的。

Java并发之线程异常捕获的更多相关文章

  1. JAVA并发,线程异常捕获

    由于线程的特性,当我们启动了线程是没有办法用try catch捕获异常的,如下例: package com.xt.thinks21_2; import java.util.concurrent.Exe ...

  2. Java并发之线程中断

    前面的几篇文章主要介绍了线程的一些最基本的概念,包括线程的间的冲突及其解决办法,以及线程间的协作机制.本篇主要来学习下Java中对线程中断机制的实现.在我们的程序中经常会有一些不达到目的不会退出的线程 ...

  3. Java并发之线程管理(线程基础知识)

    因为书中涵盖的知识点比较全,所以就以书中的目录来学习和记录.当然,学习书中知识的时候自己的思考和实践是最重要的.说到线程,脑子里大概知道是个什么东西,但很多东西都还是懵懵懂懂,这是最可怕的.所以想着细 ...

  4. Java并发之线程转储

    一.java线程转储 java的线程转储可以被定义为JVM中在某一个给定的时刻运行的所有线程的快照.一个线程转储可能包含一个单独的线程或者多个线程.在多线程环境中,比如J2EE应用服务器,将会有许多线 ...

  5. Java如何使用线程异常?

    在Java编程中,如何使用线程异常? 此示例显示如何在处理线程时处理异常. package com.yiibai; class MyThread extends Thread { public voi ...

  6. java并发之线程池的使用

    背景 当系统并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要消耗大量的系统资源. 所以需要一个办法使得线程可以 ...

  7. Java并发之——线程池

    一. 线程池介绍 1.1 简介 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡 ...

  8. Java的Hook线程及捕获线程执行异常

    import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.f ...

  9. java并发之线程执行器(Executor)

    线程执行器和不使用线程执行器的对比(优缺点) 1.线程执行器分离了任务的创建和执行,通过使用执行器,只需要实现Runnable接口的对象,然后把这些对象发送给执行器即可. 2.使用线程池来提高程序的性 ...

随机推荐

  1. AFNetWorking 之 网络请求的基本知识

    NSString *urlStr = @"http://api.openweathermap.org/data/2.5/forecast/daily"; AFHTTPRequest ...

  2. JS基础知识:Javascript事件触发列表

    Javascript是一种由Netscape的LiveScript发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言. JavaScript使我们有能 ...

  3. 解决mysql 1864 主从错误

     从字面意思看了一下是因为slave_pending_jobs_size_max默认值为16777216(16MB),但是slave接收到的slave_pending_jobs_size_max为 ...

  4. Eclipse 使用说明

    2. 使用技巧 2.1. Eclipse 打开文件所在文件夹 2.2. Mac 安装Eclipse 2.3. Eclipse 安装插件 2.4. Eclipse 工具栏不见了 2.5. Eclipse ...

  5. #图# #SPFA# #Tarjan# ----- BZOJ1179

    SPFA算法 SPFA(Shortest Path Faster Algorithm)(队列优化)算法是求单源最短路径的一种算法. 判负环(在差分约束系统中会得以体现).如果某个点进入队列的次数超过N ...

  6. Eclipse Sort Members默认之后恢复的方法

    alt+shift+s -- > m CRLF 默认一种排序之后,对话框就再也出不来了: 使用这样的方法: window - preference - Java | Java dialogs | ...

  7. 关于Visual Studio未能加载各种Package包的解决

    参考微软社区的一个答复解决了VS2013的问题: 进入VS对应的用户缓存文件夹,删掉那个Microsoft.VisualStudio.Default.cache缓存文件,就可以了. 这个错误估计是我们 ...

  8. 【Scala】Scala之Control Structures

    一.前言 前面学习了Scala的Numbers,接着学习Scala的Control Structures(控制结构). 二.Control Structures Scala中的控制结构与Java中的颇 ...

  9. 从[NOI2008志愿者招募]浅谈线性规划在网络流构图上的巧用

    首先来看一下题..http://www.lydsy.com/JudgeOnline/problem.php?id=1061 1061: [Noi2008]志愿者招募 Description 申奥成功后 ...

  10. SQL SERVER分区具体例子详解

    在日常工作中,我们会遇到以下的情况,一个表每日数万级的增长,而查询的数据通常是在本月或今年,以前的数据偶尔会用到,但查询和插入的效率越来越慢,用数据库分区会有助于解决这个问题.关于分区的理论知识网上很 ...