在多线程开发中,我们会面对很多的异常问题。但是,主线程的异常我们知道很方便捕获并且处理,但是对于子线程而言呢?
package Thread_.UncaughtException;
/**
* @program:多线程和IO
* @descripton:传统方法无法捕获子线程异常
* @author:ZhengCheng
* @create:2021/9/22-10:13
**/
public class ThreadException extends Thread {
public static void main(String[] args) {
try {
new ThreadException().start();
} catch (Exception e) {
System.out.println("I caught this Exception");
}
}
// @Override
// public void run() {
// throw new RuntimeException();
// }
//解决方案1: (不推荐) 在run方法中使用trycatch捕获异常 ,提高健壮性。
@Override
public void run() {
try {
throw new RuntimeException();
} catch (RuntimeException e) {
System.out.println("catch success");
}
}
}
测试上述代码,在主线程中,我们是无法catch到子线程抛出的异常的。故子线程的异常,我们很难使用传统方法完成。
那么有两种解决方案:
1.在run方法中加入try/catch。这样的方法可行,但是对于每一个run方法都要编写其捕获异常的处理机制,非常麻烦,不具有普适性。
2.使用UncaughtExceptionHandler
package Thread_.UncaughtException;
/**
* @program:多线程和IO
* @descripton:使用我自己的Handler处理异常
* @author:ZhengCheng
* @create:2021/9/22-10:34
**/
public class UseMyUEH implements Runnable {
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandlerDemo("我的Handler"));
new Thread(new UseMyUEH(),"MyThread-1").start();
new Thread(new UseMyUEH(),"MyThread-2").start();
new Thread(new UseMyUEH(),"MyThread-3").start();
new Thread(new UseMyUEH(),"MyThread-4").start();
}
//方案二 、使用UncaughtException
// void uncaughtexception(Thread t ,Throwable e)
@Override
public void run() {
throw new RuntimeException();
}
}
package Thread_.UncaughtException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @program:多线程和IO
* @descripton:使用UncaughtExceptionHandler接口来处理。
* @有三种实现方式,1.全局设置2.对线程单独设置3.对线程池进行设置。
* @author:ZhengCheng
* @create:2021/9/22-10:27
**/
public class UncaughtExceptionHandlerDemo implements Thread.UncaughtExceptionHandler {
private String name ;
public UncaughtExceptionHandlerDemo(String name) {
this.name = name;
}
@Override
public void uncaughtException(Thread t, Throwable e) {
Logger logger = Logger.getAnonymousLogger();
logger.log(Level.WARNING,"线程异常"+t.getName()+"被终止了");
System.out.println(name+"捕获了"+t.getName()+"异常:"+e);
}
}
通过这样的方法,我们能够合理的批量处理子线程的异常。作为一个全局处理的方式。将所有的子线程异常,在实际开发中,可以提交到日志保存,或者交给一个总的异常监控系统。
三个小问题:
1.java的异常体系
2.如何处理全局异常?为什么要全局处理?
3.run方法是否可以抛出异常?如果抛出异常,线程的状态会怎么样?
(不能抛出异常) 因为在原生的run方法中,是没有抛出异常的。只能自己进行try/catch
如果有异常了,线程会关闭。
4.线程中如何处理某个未处理异常?
使用UncaughtExceptionHandler进行处理。
在多线程开发中,主线程能方便地捕获异常,但子线程的异常处理较为复杂。传统的try/catch方式在每个run方法中实现,不具备普适性。本文介绍了使用UncaughtExceptionHandler进行全局异常处理的方法,便于批量处理子线程异常,例如记录到日志或接入异常监控系统。同时讨论了Java异常体系、全局异常处理的原因、run方法是否能抛出异常及其对线程状态的影响,以及如何处理未处理的线程异常。
338

被折叠的 条评论
为什么被折叠?



