线程异常处理及异常传递

可以给线程指定异常处理类来捕获异常进行自定义处理。

线程中的异常可通过线程组异常处理来实现异常传递,线程组 ThreadGroup 实现了 Thread.UncaughtExceptionHandler 接口。

异常处理

在 Java 多线程技术中,可以对多线程中的异常进行捕捉,使用的是 UncaughtExceptionHandler 类,可以对发生的异常进行有效的处理。

  1. 创建线程

    1
    2
    3
    4
    5
    6
    7
    8
    public class MyThread extends Thread {

    @Override
    public void run() {
    String username = null;
    System.out.println(username.hashCode());
    }
    }
  2. 线程异常处理测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    public class MainCatchException {
    public static void main(String[] args) {

    MyThread t1 = new MyThread();
    t1.setName("线程t1");
    t1.start();

    MyThread t2 = new MyThread();
    t2.setName("线程t2");
    t2.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread t2, Throwable e) {
    System.out.println("线程:" + t2.getName() + " 出现了异常");
    e.printStackTrace();
    }
    });
    t2.start();

    MyThread t3 = new MyThread();
    t3.setName("线程t3");
    t3.start();

    MyThread t4 = new MyThread();
    MyThread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread t4, Throwable e) {
    System.out.println("默认线程异常处理:" + t4.getName());
    e.printStackTrace();
    }
    });
    t4.setName("线程t4");
    t4.start();
    }
    }

异常传递

Java 的线程组实现了 Thread.UncaughtExceptionHandler 接口,在使用线程组时,可以重写 void uncaughtException(Thread t, Throwable e) 方法,使异常可以在线程组中的线程传递,即其中一个线程异常,线程组中的线程都会抛出此异常。

  1. 创建线程

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public class MyThread extends Thread {

    private String num = "a";

    public MyThread() {
    super();
    }

    public MyThread(ThreadGroup threadGroup, String name) {
    super(threadGroup, name);
    }

    @Override
    public void run() {
    int numInt = Integer.parseInt(num);
    System.out.println("在线程中打印:" + (numInt + 1));
    }
    }
  2. 线程组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class MyThreadGroup extends ThreadGroup {

    public MyThreadGroup(String name) {
    super(name);
    }

    @Override
    public void uncaughtException(Thread t, Throwable e) {
    super.uncaughtException(t, e);
    System.out.println("线程组的异常处理");
    e.printStackTrace();
    }
    }
  3. 自定义异常处理类

    1
    2
    3
    4
    5
    6
    7
    public class ObjectUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread t, Throwable e) {
    System.out.println("对象的异常处理");
    e.printStackTrace();
    }
    }
    1
    2
    3
    4
    5
    6
    7
    public class StateUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread t, Throwable e) {
    System.out.println("静态的异常处理");
    e.printStackTrace();
    }
    }
  4. Main 测试类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class MainTest {

    public static void main(String[] args) {
    MyThreadGroup group = new MyThreadGroup("我的线程组");
    MyThread myThread1 = new MyThread(group, "我的线程1");
    MyThread myThread2 = new MyThread(group, "我的线程2");

    // myThread.setUncaughtExceptionHandler(new ObjectUncaughtExceptionHandler());
    // MyThread.setDefaultUncaughtExceptionHandler(new StateUncaughtExceptionHandler());

    myThread1.start();
    myThread2.start();
    }
    }
  5. 运行输出结果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    线程组的异常处理
    线程组的异常处理
    Exception in thread "我的线程2" Exception in thread "我的线程1" java.lang.NumberFormatException: For input string: "a"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:580)
    at java.lang.Integer.parseInt(Integer.java:615)
    at com.java.jdk.thread.exception.Demo1.MyThread.run(MyThread.java:17)
    java.lang.NumberFormatException: For input string: "a"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:580)
    at java.lang.Integer.parseInt(Integer.java:615)
    at com.java.jdk.thread.exception.Demo1.MyThread.run(MyThread.java:17)
    java.lang.NumberFormatException: For input string: "a"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:580)
    at java.lang.Integer.parseInt(Integer.java:615)
    at com.java.jdk.thread.exception.Demo1.MyThread.run(MyThread.java:17)
    java.lang.NumberFormatException: For input string: "a"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:580)
    at java.lang.Integer.parseInt(Integer.java:615)
    at com.java.jdk.thread.exception.Demo1.MyThread.run(MyThread.java:17)

作者

光星

发布于

2020-01-04

更新于

2022-06-17

许可协议

评论