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

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

public class NoCaughtThread  implements Runnable{@Overridepublic 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 {@Overridepublic 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
    }@Overridepublic void run() {Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {@Overridepublic void uncaughtException(Thread arg0, Throwable e) {// TODO Auto-generated method stubSystem.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

转载于:https://www.cnblogs.com/xiaoxing/p/6230056.html

JAVA Thread线程异常监控相关推荐

  1. java thread 线程销毁_手把手带你了解Java线程的实现方式及生命周期原理

    前言 我们在工作中线程技术很多情况下都能用的到,而且我们在面试的时候,线程技术基本上也是必问的.今天我来从线程的实现方式以及线程的生命周期做一个全面的讲解与分析,帮助大家能更好的去了解线程技术. 概念 ...

  2. java thread 线程_Java Thread类简述

    今天我们来看下java.lang.Thread这个类. 在学习Thread类之前,先看下线程相关知识:线程的几种状态.上下文切换,然后介绍Thread类中的方法的具体使用. 1.线程的状态 线程从创建 ...

  3. Java子线程异常及异常处理

    最近使用线程池时,了解到了在子线程中抛出异常,主线程的处理方式. Java中抛出 Exception 时必须使用 try..catch 块处理,但是抛出 RuntimeException 和 Erro ...

  4. 错误记录一:线程通信时抛出Exception in thread “Thread-0” java.lang.IllegalMonitorStateException异常

    错误记录一:线程通信时抛出Exception in thread "Thread-0" java.lang.IllegalMonitorStateException异常 完整异常: ...

  5. java 线程崩溃_java语言中application异常退出和线程异常崩溃的捕获方法,并且在捕获的钩子方法中进行异常处理...

    1.application应用程序注入自定义钩子程序 java语言本身提供一个很好的Runtime类,可以使我们很好的获取运行时信息.其中有一个方法是 public void addShutdownH ...

  6. Java多线程:捕获线程异常

    你处理过多线程中的异常吗?如何捕获多线程中发生的异常?捕获子线程的异常与捕获当前线程的异常一样简单吗? 除了try catch.Java中还可以通过异常处理器UncaughtExceptionHand ...

  7. Java 里的thread (线程)简介

    在Java里 thread 就是线程的意思. 说到线程的概念, 自然离不开另外两个词: 程序和进程. 从最基本的程序讲起: 一. 什么是程序(Program) 所谓程序, 就是1个严格有序的指令集合. ...

  8. java线程带来的异常,java多线程练习之捕获子线程异常例子

    本文章给大家介绍java多线程练习之捕获子线程异常一个实例,希望对大家会有所帮助. java多线程程序中,所有线程都不允许抛出未捕获的checked exception,也就是说各个线程需要自己把自己 ...

  9. Java笔记11-【异常、线程】

    主要内容 异常.线程 第一章 异常 1.1 异常概念 异常,就是不正常的意思.在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响.在程序中的意思就是: 异常 :指 ...

最新文章

  1. android o 全机型推送,氢OS(Android O)官方更新推送 一加两款机型完成适配
  2. Make Even(800)
  3. 从fork-join /线程池调用的Singelton bean中的访问spring请求范围缓存
  4. spring学习(27):通过setter依赖注入
  5. mxf高速发展和数字电影母版制作技术
  6. 如何应对互联网界的奇葩面试题!
  7. 日文邮件变成乱码解决方案
  8. 轻量级java开发工具_成为 Java 程序员必备的 5 个工具
  9. 判断字符串中是否存在的几种方案:string.indexof、string.contains、list.contains、list.any几种方式效率对比...
  10. 【漏洞利用】信息泄露漏洞详解
  11. 冰点还原8.53破解版
  12. 什么是收集服务器配置信息,配置rsyslog服务器收集Cisco交换机日志信息操作指引...
  13. java mail 20m附件,发送邮件时附件大小不能超过20M,否则无法发送
  14. 圣剑传说 玛娜传奇(Legend of Mana)(LOM)副原料取得方法
  15. 签名证书(.keystore)生成指南
  16. CString - 详解
  17. Arduino控制PCF8574
  18. Unity中通过按键更换材质球纹理图片
  19. flex布局强制换行(flex-wrap:wrap)之后,去掉最下面一层多余的间隙。
  20. Java前端学习(Day 1)

热门文章

  1. spring boot中@ResponseBody等注解的作用与区别
  2. select2 4.0.8 + , 动态搜索数据
  3. 划重点了!网络推广网站在建设时期该如何进行优化?
  4. windows server 查看 删除事件_蓝队护网 之Windows服务器加固
  5. Linux内核链表交换节点,[笔记]Linux内核链表:结点的插入、删除以及链表的遍历...
  6. 修复Linux系统内核TCP漏洞,修复Linux TCP SACK PANIC 远程拒绝服务漏洞
  7. bootstranp选项卡怎么把每个选项卡里面的表单分开提交_EXCEL 宏应用基础知识,利用已实现的宏,制作自己的功能选项卡...
  8. sql中ifnull不生效_数据科学家常见的5个SQL面试问题
  9. 微信小程序-页面跳转传值
  10. Node初学(二)Promise/Deferred模式,异步调用