【Java 多线程】Java中主线程如何捕获子线程抛出的异常

转载 2017年01月03日 15:41:07

首先明确线程代码的边界。其实很简单,Runnable接口的run方法所界定的边界就可以看作是线程代码的边界。Runnable接口中run方法原型如下:

public void run();

而所有的具体线程都实现这个方法,所以这里就明确了一点,线程代码不能抛出任何checked异常。所有的线程中的checked异常都只能被线程本身消化掉。:) 这样本身也是符合线程的设计理念的,线程本身就是被看作独立的执行片断,它应该对自己负责,所以由它来消化所有的checked异常是很正常的。
这样就回答了楼主的第一个问题:checked异常一定要在线程内部消化。

但是,线程代码中是可以抛出错误(Error)和运行级别异常(RuntimeException)的。Error俺们可以忽略,因为通常Error是应该留给vm的,而RuntimeException确是比较正常的,如果在运行过程中满足了某种条件导致线程必须中断,可以选择使用抛出运行级别异常来处理,如下:

public void run() {
if (...) throw new RuntimeException();
}

当线程代码抛出运行级别异常之后,线程会中断。:)这点java中解释得很清楚:
@see Thread
All threads that are not daemon threads have died, either by returning from the call to the run method or “by throwing an exception that propagates beyond the run method”.
但是对于invoke此线程的主线程会产生什么影响呢?主线程不受这个影响,不会处理这个RuntimeException,而且根本不能catch到这个异常。会继续执行自己的代码 :)
所以得到结论:线程方法的异常只能自己来处理。



但是,给某个thread设置一个UncaughtExceptionHandler,可以确保在该线程出现异常时能通过回调UncaughtExceptionHandler接口的public void uncaughtException(Thread t, Throwable e) 方法来处理异常,这样的好处或者说目的是可以在线程代码边界之外(Thread的run()方法之外),有一个地方能处理未捕获异常。但是要特别明确的是:虽然是在回调方法中处理异常,但这个回调方法在执行时依然还在抛出异常的这个线程中!另外还要特别说明一点:如果线程是通过线程池创建,线程异常发生时UncaughtExceptionHandler接口不一定会立即回调。代码示例如下:

package study20170103;

/**
 * Created by apple on 17/1/3.
 */
public class ThreadTest extends ThreadGroup{

    private ThreadTest(){
        super("ThreadTest");
    }


    public static void main(String[] args) {
        new Thread(new ThreadTest(),new Runnable() {//传入继承ThreadGroup的类对象
            @Override
            public void run() {
                throw new NullPointerException();//只能抛出unchecked异常
            }
        }).start();
    }

    public   void   uncaughtException(Thread   thread,   Throwable   exception)
    {
        /**
         * 当线程抛出unckecked异常时,系统会自动调用该函数,但是是在抛出异常的线程内执行
         */
        System.out.println(thread.getId());
        exception.printStackTrace();//example,   print   stack   trace
    }
}


比之上述方法,还有一种编程上的处理方式可以借鉴,即,有时候主线程的调用方可能只是想知道子线程执行过程中发生过哪些异常,而不一定会处理或是立即处理,那么发起子线程的方法可以把子线程抛出的异常实例收集起来作为一个Exception的List返回给调用方,由调用方来根据异常情况决定如何应对。不过要特别注意的是,此时子线程早以终结。

线程设计的理念:“线程的问题应该线程自己本身来解决,而不要委托到外部。”

相关文章推荐

如何捕获子线程异常

一 直接在主线程捕获子线程异常(此方法不可取) using System; using System.Threading; namespace CatchThreadException { ...
  • tiana0
  • tiana0
  • 2015年06月20日 18:58
  • 4772

[转]Java中主线程如何捕获子线程抛出的异常

这么来看待这个问题。首先明确线程代码的边界。其实很简单,Runnable接口的run方法所界定的边界就可以看作是线程代码的边界。Runnable接口中run方法原型如下:     >     而所有的...

java多线程中的异常处理

在java多线程程序中,所有线程都不允许抛出未捕获的checked exception,也就是说各个线程需要自己把自己的checked exception处理掉。这一点是通过java.lang.Run...

java 多线程中的异常处理

1、java多线程中,最近线程会抛异常,但是所以自然的想着通过try catche来捕获异常:try { thread1.start(); } catch (Exception e) { ...

java多线程中的异常处理 - 异常处理在多线程中的原则

如果各位觉得对自己有用,就支持一下吧 [size=14.399999618530273px]在java多线程程序中,所有线程都不允许抛出未捕获的checked exception,也就是说各个线...
  • alexchy
  • alexchy
  • 2014年08月13日 15:23
  • 371

Java多线程之捕获子线程中的异常

在某些场景下,我们经常需要使用多线程来执行任务提高性能,但是我们知道正常的线程是无法处理异常的,一旦出现异常就会传播到控制台。这个时候我们需要在线程里面处理异常怎么办呢,我们可以使用Executor来...

java中给出一个主线程如何捕获子线程异常的例子

马克-to-win:首先我们看主线程如何捕获子线程的异常 例:1.5.4-本章源码 import java.lang.Thread.UncaughtExceptionHandler; c...

如何捕获java线程中的逃逸的异常

由于Java线程的本质特征,当抛出异常的时候就终止了如果再进行catch,都不在一个线程里面,所以无法捕捉到异常。Java线程中,要在run()方法中把一切的异常都处理掉,可以使用try-catch块...

java捕获线程异常

在jdk1.5之前,线程不允许抛出异常(各个线程要把自己的checked exception处理掉),但是无法避免的是uncheckedexception,也就是RuntimeException,当...

java多线程编程之捕获子线程异常示例

java多线程程序中所有线程都不允许抛出未捕获的checked exception,也就是说各个线程需要自己把自己的checked exception处理掉。 但是无法避免的是unchecked e...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【Java 多线程】Java中主线程如何捕获子线程抛出的异常
举报原因:
原因补充:

(最多只允许输入30个字)