新建线程的异常处理
来源:互联网 发布:淘宝致一科技 编辑:程序博客网 时间:2024/06/08 20:12
将Thinking injava 12.2.14节进行总结
一般情况:
由于线程的本质特性,使你不能捕获从线程中逃逸的异常。一旦异常逃出任务的run方法,它就会向外传播到控制台
package hfi.bellychang.Task.CaptureException.Demo01;import org.junit.Test;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * 子线程中的异常在主线程中是捕捉不到的 * Created by Administrator on 2017/6/26. */class ExceptionThread implements Runnable { Logger logger = LoggerFactory.getLogger(ExceptionThread.class); ExceptionThread(){ super(); logger.info("exception happens in ExceptionThread"); } @Override public void run() { throw new RuntimeException(); }}public class MainThread { @Test public void test() { ExecutorService exec = Executors.newCachedThreadPool(); exec.execute(new ExceptionThread()); }}
运行结果:异常向外传播到控制台
问题自然来了,如何捕捉子线程中的异常,使其不直接向外传播到控制台呢?
解决方案1:
实现ThreadFactory接口,在newThread方法中附加异常处理器。将这个工厂传递给Executors创建新的ExecutorService的方法,就设置了这个线程池专有的未捕获异常的处理器
package hfi.bellychang.Task.CaptureException.Demo02;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ThreadFactory;/** * 在主线程中捕获子线程产生的异常 * 要修改Executor产生钱程的方式 * Thread.UncaughtExceptionHandler是Java SE5 中的新接口, * 它允许你在每个Thread对象上都附着一个异常处理器o * Thread.UncaughtExceptionHandler。uncaughtException()会在线程因未捕获的异常而临近死亡时被调用 * * Created by Administrator on 2017/6/26. */class ExceptionThread2 implements Runnable { public void run() { throw new RuntimeException(); }}class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { Logger logger = LoggerFactory.getLogger(MyUncaughtExceptionHandler.class); @Override public void uncaughtException(Thread t, Throwable e) { logger.info("caught " + e); }}/** * 创建了一个新类型的ThreadFactory, 它将在每个新创建的Thread对象上 * 附着一个Thread.UncaughtExceptionHandler */class HandlerThreadFactory implements ThreadFactory { Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public Thread newThread(Runnable r) { Thread t = new Thread(r); logger.info("created " + t); //附着一个Thread.UncaughtExceptionHandler t.setUncaughtExceptionHandler( new MyUncaughtExceptionHandler()); return t; }}/** * 示例使得你可以按照具体情况逐个地设置处理器 * 意思是通过不同的ThreadFactory的实现 附着不同的ExceptionHandler? */public class MainThread { public static void main(String[] args) { //我们将这个工厂传递给Executors创建新的ExecutorService的方法: //此线程池专有的未捕获异常处理器 ExecutorService exec = Executors.newCachedThreadPool( new HandlerThreadFactory()); exec.execute(new ExceptionThread2()); }}
执行结果
可见通过不同的ThreadFactory的实现,附着不同的ExceptionHandler,可以按照具体情况逐个地设置处理器
解决方案2:
在Thread类中设置一个静态域,并将这个处理器设置为Thread类的默认的未捕获异常处理器 Thread.setDefaultUncaughtExceptionHandler,但这样不能指定某个Thread使用哪个异常处理器
package hfi.bellychang.Task.CaptureException.Demo03;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * 通过这种方式,在主线程中捕获到了子线程中的异常 * Created by Administrator on 2017/6/26. */class ExceptionThread implements Runnable { public void run() { throw new RuntimeException(); }}class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public void uncaughtException(Thread t, Throwable e) { logger.info("caught " + e); }}public class MainThread { public static void main(String[] args) { Thread.setDefaultUncaughtExceptionHandler( new MyUncaughtExceptionHandler()); ExecutorService exec = Executors.newCachedThreadPool(); exec.execute(new ExceptionThread()); }}
通过以上的两种方式,就可以将异常信息在catch中写入日志文件,在日志文件中查看子线程是否发生异常,对程序的运行情况有所掌握
阅读全文
0 0
- 新建线程的异常处理
- hadoop的datanode新建异常处理
- Hadoop的datanode新建异常处理
- java线程异常的处理
- 线程池的异常处理
- 线程中断异常的处理 abort()
- 线程中不可控制异常的处理
- 关于线程中异常的处理
- Java 线程池的异常处理机制
- 线程中的异常处理
- 线程异常处理
- 处理线程异常
- 线程中的异常处理
- Java 线程异常处理
- Qt新建线程的方法
- Qt 新建线程的方法
- 线程池异常统一处理
- 线程意外终止异常处理
- UNIX环境高级编程-读书笔记-进程
- html入门(一)
- 深入理解Spark 2.1 Core (九):迭代计算和Shuffle的原理与源码分析
- 第5章 数据类型和运算符
- 一种新的类型的密码管理软件Lesspass
- 新建线程的异常处理
- UNIX环境高级编程-读书笔记-网络编程(一)
- Codeforces Gym 101142 F. Folding
- Mapped Statements collection does not contain value for
- 阿里云centos7 部署java+tomcat+mysql运行环境
- 打印日志小结
- UNIX环境高级编程-读书笔记-网络编程(二)
- CButton重绘图片实现自由缩放和拖动
- 定制Eclipse右键new菜单