多线程并发系列(八):线程异常处理及异常传递

star2017 1年前 ⋅ 506 阅读

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

线程中的异常可通过线程组异常处理来实现异常传递,线程组 ThreadGroup 实现了

异常处理

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

  1. 创建线程

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

    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. 创建线程

    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. 线程组

    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. 自定义异常处理类

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

    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. 运行输出结果

    线程组的异常处理
    线程组的异常处理
    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)
    
更多内容请访问:IT源点

相关文章推荐

全部评论: 0

    我有话说: