一、场景描述:单线程程序可以用try...catch捕获程序的异常,而在多线程程序的时候是无法使用try...catch捕获。

示例1:多线程发生异常,无法使用try...catch捕获问题

public class NoCaughtThread  implements Runnable{
@Override
public void run() {
System.out.println(3 / 2);
System.out.println(3 / 0);
System.out.println(3 / 1);
} public static void main(String[] args) {
try {
Thread thread = new Thread(new NoCaughtThread());
thread.start();
} catch (Exception e) {
System.out.println("==Exception: " + e.getMessage());
}
}
}

运行结果:

1
Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
at threadtest.NoCaughtThread.run(NoCaughtThread.java:7)
at java.lang.Thread.run(Thread.java:724)

显然这并非程序设定异常捕获,此时try...catch无法捕获线程的异常。此时,如果线程因为异常而终止执行将无法检测到异常。究其原因Thread类run()方法是不抛出任何检查型异常的,而自身却可能因为一个异常而被中止。

二、解决方式大致有两种:① 在run()中设置对应的异常处理,主动方法来解决未检测异常;② Thread类API中提供Interface接口UncaughtExceptionHandler,该接口包含uncaughtException方法,它能检测出某个未捕获的异常而终结的情况;

示例2:主动的检测异常

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class InitiativeCaught {
public static void main(String[] args) {
InitialtiveThread initialtiveThread = new InitialtiveThread() ;
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(initialtiveThread);
exec.shutdown();
}
} class InitialtiveThread implements Runnable {
@Override
public void run() {
Throwable thrown = null;
try {
System.out.println(3 / 2);
System.out.println(3 / 0);
System.out.println(3 / 1);
} catch (Throwable e) {
thrown = e;
} finally {
threadDeal(this, thrown);
}
} public void threadDeal(Runnable r, Throwable t) {
System.out.println("==Exception: " + t.getMessage());
}
}

运行结果:

1
==Exception: / by zero

此时是主动捕获异常并做处理,得到想要的结果。

示例3:Thread类API中提供UncaughtExceptionHandler接口捕获异常,要求检测线程异常,发生异常设置为重复调用三次之后结束线程。

import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class ThreadMonitor implements Runnable {
private int data; // 可设置通过构造传参
private int control = 0;
private static final int MAX = 3; // 设置重试次数 public ThreadMonitor(int i) {
this.data = i;
}
public ThreadMonitor() {
// TODO Auto-generated constructor stub
} @Override
public void run() {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread arg0, Throwable e) {
// TODO Auto-generated method stub
System.out.println("==Exception: " + e.getMessage());
String message = e.getMessage();
if( control==MAX ){
return ;
}else if( "ok".equals(message) ){
return ;
}else if ( "error".equals(message) ) {
new Thread() {
public void run() {
try {
System.out.println("开始睡眠。");
Thread.sleep(1 * 1000);
control++ ;
System.out.println("睡眠结束,control: "+ control);
myTask(data) ;
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
}else{
return ;
}
}
}); myTask(data) ; } @SuppressWarnings("finally")
public void myTask(int data){
boolean flag = true ;
try {
System.out.println(4 / data);
} catch (Exception e) {
flag = false ;
} finally {
if( flag ){
throw new RuntimeException("ok");
}else{
throw new RuntimeException("error");
}
}
} public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
ThreadMonitor threadMonitor = new ThreadMonitor(0);
exec.execute(threadMonitor);
exec.shutdown();
}
}

运行结果:

==Exception: error
开始睡眠。
睡眠结束,control: 1
==Exception: error
开始睡眠。
睡眠结束,control: 2
==Exception: error
开始睡眠。
睡眠结束,control: 3
==Exception: error

此时,可以正常捕获线程因除数为零造成的中断。其中:

(1) 在Thread类API中提供Interface接口UncaughtExceptionHandler,该接口包含一个uncaughtException方法,它能检测出某个由于未捕获的异常而终结的情况。定义如下:

UncaughtExceptionHandler接口:  public static interface Thread.UncaughtExceptionHandler

uncaughtException方法: public void uncaughtException(Thread t, Throwable e)

(2) uncaughtException方法会捕获线程的异常,此时需要覆写该方法设定自定义的处理方式。

(3) 设置UncaughtExceptionHandler异常处理:

方式一:通过Thread提供的静态static方法,设置默认异常处理:public static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler ux)

方式二:通过方法:public void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)

(4) UncaughtExceptionHandler异常处理需要设置在run()方法内,否则无法捕获到线程的异常。

(5) 参考链接:

JAVA下内存池启动程序:http://www.cnblogs.com/zhujiabin/p/5404771.html

JAVA下多线程异常处理:http://blog.csdn.net/u013256816/article/details/50417822

JAVA Thread线程异常监控的更多相关文章

  1. Java Thread线程控制

    一.线程和进程 进程是处于运行中的程序,具有一定的独立能力,进程是系统进行资源分配和调度的一个独立单位. 进程特征: A.独立性:进程是系统中独立存在的实体,可以拥有自己独立的资源,每个进程都拥有自己 ...

  2. Java Thread(线程)案例详解sleep和wait的区别

    上次对Java Thread有了总体的概述与总结,当然大多都是理论上的,这次我将详解Thread中两个常用且容易疑惑的方法.并通过实例代码进行解疑... F区别 sleep()方法 sleep()使当 ...

  3. 学习接水系统(java+thread线程)

    (一)项目框架分析 对于学生并发接水项目,根据面向对象的思想,需要创建两个对象,即学生和水龙头. 接下来主要讲解不排队接水和排队接水两张情况. 项目的目录文件如下: (二)不排队接水 假设有四个学生小 ...

  4. Java利用线程工厂监控线程池

    目录 ThreadFactory 监控线程池 扩展线程池 扩展线程池示例 优化线程池大小 线程池死锁 线程池异常信息捕获 ThreadFactory 线程池中的线程从哪里来呢?就是ThreadFoct ...

  5. java thread 线程锁同步,锁,通信

    12.线程同步 当多个线程访问同一个数据时,非常容易出现线程安全问题.这时候就需要用线程同步 Case:银行取钱问题,有以下步骤: A.用户输入账户.密码,系统判断是否登录成功 B.用户输入取款金额 ...

  6. java thread 线程40个问题汇总

    http://www.codeceo.com/article/40-java-thread-problems.html 1.多线程有什么用? 一个可能在很多人看来很扯淡的一个问题:我会用多线程就好了, ...

  7. communication between threads 线程间通信 Programming Concurrent Activities 程序设计中的并发活动 Ada task 任务 Java thread 线程

    Computer Science An Overview _J. Glenn Brookshear _11th Edition activation 激活 parallel processing 并行 ...

  8. 基于 JVMTI 实现 Java 线程的监控(转)

    随着多核 CPU 的日益普及,越来越多的 Java 应用程序使用多线程并行计算来充分发挥整个系统的性能.多线程的使用也给应用程序开发人员带来了巨大的挑战,不正确地使用多线程可能造成线程死锁或资源竞争, ...

  9. Java并发(六)线程池监控

    目录 一.线程池监控参数 二.线程池监控类 三.注意事项 在上一篇博文中,我们介绍了线程池的基本原理和使用方法.了解了基本概念之后,我们可以使用 Executors 类创建线程池来执行大量的任务,使用 ...

随机推荐

  1. 代码的坏味道(17)——夸夸其谈未来性(Speculative Generality)

    坏味道--夸夸其谈未来性(Speculative Generality) 特征 存在未被使用的类.函数.字段或参数. 问题原因 有时,代码仅仅为了支持未来的特性而产生,然而却一直未实现.结果,代码变得 ...

  2. 基于select的python聊天室程序

    python网络编程具体参考<python select网络编程详细介绍>. 在python中,select函数是一个对底层操作系统的直接访问的接口.它用来监控sockets.files和 ...

  3. RavenDB官网文档翻译系列第一

    本系列文章主要翻译自RavenDB官方文档,有些地方做了删减,有些内容整合在一起.欢迎有需要的朋友阅读.毕竟还是中文读起来更亲切吗.下面进入正题. 起航 获取RavenDB RavenDB可以通过Nu ...

  4. 将mvc2升级到mvc4

    万万没想到大二时候参加中国大学生计算机大赛的一个项目正是当前项目所需! 时间紧任务重,还好之前的项目稍微改改即可交付使用,但是还是缺少一些功能模块,巧合的是,缺少的这个功能模块是今年刚刚完成的基于mv ...

  5. 分享我对 ASP.NET vNext 的一些感受,也许多年回过头看 So Easy!

    写在前面 阅读目录: Visual Studio "14" CTP 关于 ASP.NET vNext ASP.NET vNext 实践 后记 ASP.NET vNext 发布已经过 ...

  6. 如何扩展 Visual Studio 编辑器

    在 Visual Studio 2010 的时代,扩展 Visual Studio 的途径有很多,开发者可以选择宏.Add-in.MEF 和 VSPackages 进行自定义的扩展.但是宏在 Visu ...

  7. js自动提示查询添加功能(不是自动补全)

    在工作中遇到查询某些数据,并添加到一个列表里的时候,写了一个小功能. 优点: 1.纯手工JS代码,不需要任何js框架,复制下来就能测试,无毒副作用. 2.通过模糊查询快速定位数据,并添加到列表里. 缺 ...

  8. 事件EVENT与waitforsingleobject的使用

    事件event与waitforsingleobject的配合使用,能够解决很多同步问题,也可以在数据达到某个状态时启动另一个线程的执行,如报警. event的几个函数: 1.CreateEvent和O ...

  9. GitHub实战系列~2.把本地项目提交到github中 2015-12-10

    GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...

  10. 05.GitHub实战系列~5.发布版本之分支操作+Tag讲解 2015-12-14

    GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...