新建线程的异常处理

来源:互联网 发布:淘宝致一科技 编辑:程序博客网 时间: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中写入日志文件,在日志文件中查看子线程是否发生异常,对程序的运行情况有所掌握
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 华为v9玩飞车卡怎么办 苹果7耳机转换器不支持怎么办 华为mate10耳机声音小怎么办 200打一年到期了怎么办 手机欠费变成2g怎么办 手机4g网用不了怎么办 手机玩王者荣耀卡怎么办 华为隐私空间密码忘记了怎么办 华为手机王者太卡怎么办 华为手机太卡怎么办呢 华为手机5x太卡!怎么办 华为手机玩游戏时太卡了怎么办? 买到华为翻新机怎么办 华为畅享8声音小怎么办 华为5a安全模式怎么办 手机跳屏怎么办金立 苹果手机触控不灵敏怎么办 华为mate8手机声音小怎么办 华为mate9相机无法对焦怎么办 新疆外地电信卡信号差怎么办 华为手机搜索不到wifi怎么办 华为浏览器恢复只有一个页面怎么办 华为手机触摸屏没反应怎么办 快递不给送上楼怎么办 华为荣耀手机声音小怎么办 华为手机来电铃声小怎么办 s弯出来时老压线怎么办 苹果7p手机弯了怎么办 小米手机摔弯了怎么办 华为畅享5没声音怎么办 掌阅语音闪退怎么办 华为mate开屏成排线怎么办 华为mate8电池坏了怎么办 8plus拍照不清晰怎么办 荣耀手环3丢了怎么办 华为mate9手机声音小怎么办 华为麦芒6丢了怎么办 华为麦芒4无法访问移动网络怎么办 自拍时屏幕是白的怎么办 华为麦芒5手机音量小怎么办 小米5x玩王者卡怎么办