栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java多线程之多线程异常捕捉

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java多线程之多线程异常捕捉

  一:为什么要单独讲多线程的异常捕捉呢?

先看个例子:

public class ThreadException implements Runnable{
  @Override
  public void run() {
    throw new RuntimeException();
  }
  //现象:控制台打印出异常信息,并运行一段时间后才停止
  public static void main(String[] args){
    //就算把线程的执行语句放到try-catch块中也无济于事
    try{
      ExecutorService exec = Executors.newCachedThreadPool();
      exec.execute(new ThreadException());
    }catch(RuntimeException e){
      System.out.println("Exception has been handled!");
    }
  }
}

  在run中手动抛出了一个运行时异常,在main中启动线程,catch语句块中捕捉下异常,捕捉到打印一句话。运行结果如下图:

  发现异常被抛到了控制台,没有打印catch块中的语句。

  结论:多线程运行不能按照顺序执行过程中捕获异常的方式来处理异常,异常会被直接抛出到控制台(由于线程的本质,使得你不能捕获从线程中逃逸的异常。一旦异常逃逸出任务的run方法,它就会向外传播到控制台,除非你采用特殊的形式捕获这种异常。),这样会让你很头疼,无法捕捉到异常就无法处理异常而引发的问题。

  于是,我们一定会想如何在多线程中捕捉异常呢?

二、多线程中捕捉异常

  我们来按照下面的步骤完成这次实验:

  1.定义异常处理器

   要求,实现 Thread.UncaughtExceptionHandler的uncaughtException方法,如下:


class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
  
  @Override
  public void uncaughtException(Thread t, Throwable e) {
    System.out.println("caught  "+e);
  }
}

  2.定义使用该异常处理器的线程工厂


class HanlderThreadFactory implements ThreadFactory{
  @Override
  public Thread newThread(Runnable r) {
    System.out.println(this+"creating new Thread");
    Thread t = new Thread(r);
    System.out.println("created "+t);
    t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());//设定线程工厂的异常处理器
    System.out.println("eh="+t.getUncaughtExceptionHandler());
    return t;
  }
}

  3.定义一个任务,让其抛出一个异常


class ExceptionThread implements Runnable{
  @Override
  public void run() {
    Thread t = Thread.currentThread();
    System.out.println("run() by "+t);
    System.out.println("eh = "+t.getUncaughtExceptionHandler());
    throw new RuntimeException();
  }
}

  4.调用实验


public class ThreadExceptionUncaughtExceptionHandler{
  public static void main(String[] args){
    ExecutorService exec = Executors.newCachedThreadPool(new HanlderThreadFactory());
    exec.execute(new ExceptionThread());
  }
}

  运行结果如下图:

三、结论

  在java中要捕捉多线程产生的异常,需要自定义异常处理器,并设定到对应的线程工厂中(即第一步和第二步)。

四、拓展

  如果你知道将要在代码中处处使用相同的异常处理器,那么更简单的方式是在Thread类中设置一个静态域,并将这个处理器设置为默认的未捕获处理器。

这个处理器只有在不存在线程专有的未捕获异常处理器的情况下才会被调用。

public static void main(String[] args){
    Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
    ExecutorService exec =Executors.newCachedThreadPool();
    exec.execute(new ExceptionThread());
}

以上就是本文针对Java多线程之多线程的异常捕捉的全部内容,本文如有理解错误地方,欢迎批评改正。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/151279.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号