JAVA并发编程-线程异常

1、JAVA异常体系图

2、如何全局处理异常?为什么要全局处理?可不可以不处理?

线程的未捕获异常UncaughtExcption应该如何处理

1、为什么需要UncaughtExcptionHandler?

  • 主线程可以轻松发现异常,子线程却不行

主线程往往会打印茫茫多的日志,子线程的异常信息可能埋没在其中没有被发现了,比如这段代码

publicclassExceptionInChildThreadimplementsRunnable{

publicstaticvoidmain(String[] args){

new Thread(new ExceptionInChildThread()).start();

for (int i = 0; i < 10000; i++) {

System.out.println(i);

}

}

@Override

publicvoidrun(){

thrownew RuntimeException();

}

}

如果不通过查找去看的话,很容易忽略掉子线程的异常

  • 子线程异常无法用传统方式捕获(try-catch)

/**

* 1. 不加try catch抛出4个异常,都带线程名字

* 2. 加了try catch,期望捕获到第一个线程的异常,线程234不应该运行,希望看到打印出Caught Exception

* 3. 执行时发现,根本没有Caught Exception,线程234依然运行并且抛出异常

*

* 说明线程的异常不能用传统方法捕获

*/

publicclassNotCatchDirectlyimplementsRunnable{

@Override

publicvoidrun(){

thrownew RuntimeException();

}

publicstaticvoidmain(String[] args)throws Exception {

try {

new Thread(new NotCatchDirectly(), "MyThread-1").start();

Thread.sleep(300);

new Thread(new NotCatchDirectly(), "MyThread-2").start();

Thread.sleep(300);

new Thread(new NotCatchDirectly(), "MyThread-3").start();

Thread.sleep(300);

new Thread(new NotCatchDirectly(), "MyThread-4").start();

Thread.sleep(300);

} catch (RuntimeException e) {

System.out.printf("catch the exception");

}

}

}

并没有得到catch到异常,原因是catch只能捕获当前线程中的异常,在main中使用try-catch只会捕获main中产生的异常

  • 不能直接捕获的后果、提高健壮性

两种解决方法

1、(不好)手动在每个run方法里面进行try-catch

2、(推荐)利用UncaughtExcptionHandler

  • void uncaughtException(Thread t, Throwable e)
  • 异常处理器的调用策略
  • 自己实现

    • 给程序统一设置;
    • 给每个线程单独设置;
    • 给线程池设置

handler类:

publicclassOwnExceptionHandlerimplementsThread.UncaughtExceptionHandler{

private String name;

publicOwnExceptionHandler(String name){

this.name = name;

}

@Override

publicvoiduncaughtException(Thread t, Throwable e){

Logger logger = Logger.getAnonymousLogger();

logger.log(Level.WARNING, "线程异常,终止" + t.getName());

logger.log(Level.INFO, name + "捕获了异常:" + t.getName() + "异常");

}

}

使用handler的主类

publicclassUseOwnHandlerimplementsRunnable{

@Override

publicvoidrun(){

thrownew RuntimeException();

}

publicstaticvoidmain(String[] args)throws InterruptedException {

Thread.setDefaultUncaughtExceptionHandler(new OwnExceptionHandler("自己的捕获器"));

new Thread(new UseOwnHandler(), "MyThread-1").start();

Thread.sleep(300);

new Thread(new UseOwnHandler(), "MyThread-2").start();

Thread.sleep(300);

new Thread(new UseOwnHandler(), "MyThread-3").start();

Thread.sleep(300);

new Thread(new UseOwnHandler(), "MyThread-4").start();

Thread.sleep(300);

}

}

结果如下,可以看出handler捕获到了子线程的异常并进行了处理。

以上是 JAVA并发编程-线程异常 的全部内容, 来源链接: utcz.com/a/27525.html

回到顶部