Java 未捕获异常处理
发布于: 2020 年 10 月 13 日
思考:
实际工作中:如何全局处理异常?为什么要全局处理?不处理行不行?
UncaughtException
线程的异常不能用传统方法捕获
主线程可以轻松发现异常,子线程却不行
子线程异常无法用传统方法捕获
不能直接捕获的后果、提高健壮性
方式一:不加 try catch抛出 4 个异常,都带线程名字
public class CantCatchDirectly implements Runnable { public static void main(String[] args) throws InterruptedException { new Thread(new CantCatchDirectly(), "MyThread-1").start(); Thread.sleep(300); new Thread(new CantCatchDirectly(), "MyThread-2").start(); Thread.sleep(300); new Thread(new CantCatchDirectly(), "MyThread-3").start(); Thread.sleep(300); new Thread(new CantCatchDirectly(), "MyThread-4").start(); } @Override public void run() { throw new RuntimeException(); }}
方式二:加了 try catch,期望捕获到第一个线程的异常,线程 234 不应该运行,希望看到打印出 Caught Exception,执行时发现,根本没有 Caught Exception,线程 234 依然运行并且抛出异常
public class CantCatchDirectly implements Runnable { public static void main(String[] args) throws InterruptedException { try { new Thread(new CantCatchDirectly(), "MyThread-1").start(); Thread.sleep(300); new Thread(new CantCatchDirectly(), "MyThread-2").start(); Thread.sleep(300); new Thread(new CantCatchDirectly(), "MyThread-3").start(); Thread.sleep(300); new Thread(new CantCatchDirectly(), "MyThread-4").start(); } catch (RuntimeException e) { System.out.println("Caught Exception."); } } @Override public void run() { throw new RuntimeException(); }}
为什么需要使用 UncaughtExceptionHandler
方案一(不推荐):手动在每个 run 方法里进行 try catch
public class CantCatchDirectly implements Runnable { public static void main(String[] args) throws InterruptedException { try { new Thread(new CantCatchDirectly(), "MyThread-1").start(); Thread.sleep(300); new Thread(new CantCatchDirectly(), "MyThread-2").start(); Thread.sleep(300); new Thread(new CantCatchDirectly(), "MyThread-3").start(); Thread.sleep(300); new Thread(new CantCatchDirectly(), "MyThread-4").start(); } catch (RuntimeException e) { System.out.println("Caught Exception."); } } @Override public void run() { try { throw new RuntimeException(); } catch (RuntimeException e) { System.out.println("Caught Exception."); } }}
方案二(推荐):利用 UncaughtExceptionHandler
UncaughtExceptionHandler 接口
void uncaughtException(Thread t, Throwable e);
异常处理器的调用策略
实现
给程序统一设置
给每个线程单独设置
给线程池设置
/** * 描述: 自己的MyUncaughtExceptionHanlder */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()); System.out.println(name + "捕获了异常" + t.getName() + "异常"); }}
public class UseOwnUncaughtExceptionHandler implements Runnable { public static void main(String[] args) throws InterruptedException { Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler("捕获器")); new Thread(new UseOwnUncaughtExceptionHandler(), "MyThread-1").start(); Thread.sleep(300); new Thread(new UseOwnUncaughtExceptionHandler(), "MyThread-2").start(); Thread.sleep(300); new Thread(new UseOwnUncaughtExceptionHandler(), "MyThread-3").start(); Thread.sleep(300); new Thread(new UseOwnUncaughtExceptionHandler(), "MyThread-4").start(); } @Override public void run() { throw new RuntimeException(); }}
思考:
run 方法是否可以抛出异常?如果抛出异常,线程的状态会怎么样?
线程中如何处理某个未处理异常?
划线
评论
复制
发布于: 2020 年 10 月 13 日 阅读数: 14
朱华
关注
见自己,见天地,见众生。 2018.08.07 加入
还未添加个人简介
评论