7.线程的八大核心基础知识之未捕获异常如何处理
Posted zhihaospace
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7.线程的八大核心基础知识之未捕获异常如何处理相关的知识,希望对你有一定的参考价值。
一.为什么需要UncaughtExceptionHandler
1.主线程可以轻松发现异常,子线程却不行
-
运行下面程序发现,子线程出现异常会在控制台显示错误信息而不会终止主线程程序,程序依旧运行很难发现错误信息
public class ExceptionInChildThread implements Runnable { @Override public void run() { throw new RuntimeException(); } public static void main(String[] args) { new Thread(new ExceptionInChildThread()).start(); for (int i = 0; i < 1000; i++) { System.out.println(i); } } }
2.子线程异常无法用传统方法捕获
-
从下面程序可以看出,当第一个线程抛出异常后程序并没有结束继续,直到三个线程都抛出异常并且主程序执行完毕。对于普通异常当捕获到第一个异常后就会异常处理不在继续执行。
-
这是由于异常发生在每一个线程的run方法中,主线程捕获不到子线程异常
public class CantCatchDirectly implements Runnable { @Override public void run() { throw new RuntimeException(); } public static void main(String[] args) { try { new Thread(new CantCatchDirectly(), "thread1").start(); Thread.sleep(100); new Thread(new CantCatchDirectly(), "thread2").start(); Thread.sleep(100); new Thread(new CantCatchDirectly(), "thread3").start(); } catch (InterruptedException e) { System.out.println("捕获到异常"); } } }
3.UncaughtExceptionHandler处理会提高程序的健壮性
二.处理线程异常两种解决方案
1.方案一(不推荐):手动在每一个run方法中进行try/catch处理
2.方案二(推荐):利用UncaughtExceptionHandler接口处理异常
-
UncaughtExceptionHandler接口
-
void uncaughtException(Thread t, Throwable e);
(1)异常处理器的调用策略
-
如果有父线程的异常处理就调用父线程的
-
如果没有则判断用户是否自己实现异常处理器,自己实现了就调用自己实现的异常处理器,没有就默认打印堆栈信息
(2)自己实现异常处理器
实现方式:
-
给程序统一设置
-
给线程独立设置
-
给线程池设置
自定义异常捕获器:实现 Thread.UncaughtExceptionHandler 接口
import java.util.logging.Level; import java.util.logging.Logger; public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { private String name; public MyUncaughtExceptionHandler(String name) { this.name = name; } @Override public void uncaughtException(Thread t, Throwable e) { Logger logger = Logger.getAnonymousLogger(); logger.log(Level.WARNING, "线程异常,终止啦" + t.getName(), e); System.out.println(name + "捕获了异常" + t.getName() + "异常" + e); } }
使用自己的异常捕获器
public class UseOwnUncaughtExceptionHandler implements Runnable { @Override public void run() { throw new RuntimeException(); } public static void main(String[] args) throws InterruptedException { Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler("捕获器1")); new Thread(new CantCatchDirectly(), "thread1").start(); Thread.sleep(100); new Thread(new CantCatchDirectly(), "thread2").start(); Thread.sleep(100); new Thread(new CantCatchDirectly(), "thread3").start(); } }
以上是关于7.线程的八大核心基础知识之未捕获异常如何处理的主要内容,如果未能解决你的问题,请参考以下文章