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 方法是否可以抛出异常?如果抛出异常,线程的状态会怎么样?

  • 线程中如何处理某个未处理异常?

用户头像

朱华

关注

见自己,见天地,见众生。 2018.08.07 加入

还未添加个人简介

评论

发布
暂无评论
Java 未捕获异常处理