我有一个Java main类,在这个类中,我启动一个新线程,在main中,它等待线程死亡。在某个时刻,我从线程抛出运行时异常,但我无法捕获从主类中的线程抛出的异常。

代码如下:

public class Test extends Thread
{
  public static void main(String[] args) throws InterruptedException
  {
    Test t = new Test();

    try
    {
      t.start();
      t.join();
    }
    catch(RuntimeException e)
    {
      System.out.println("** RuntimeException from main");
    }

    System.out.println("Main stoped");
  }

  @Override
  public void run()
  {
    try
    {
      while(true)
      {
        System.out.println("** Started");

        sleep(2000);

        throw new RuntimeException("exception from thread");
      }
    }
    catch (RuntimeException e)
    {
      System.out.println("** RuntimeException from thread");

      throw e;
    } 
    catch (InterruptedException e)
    {

    }
  }
}

有人知道为什么吗?


当前回答

使用Callable而不是Thread,然后你可以调用Future#get(),它会抛出Callable抛出的任何异常。

其他回答

这解释了线程的状态转换取决于是否发生异常:

来源:http://www-public.imtbs-tsp.eu/~gibson/Teaching/CSC7322/L8-ExceptionsAndThreads.pdf

你玩了setDefaultUncaughtExceptionHandler()和线程类的类似方法吗?来自API:“通过设置默认的未捕获异常处理程序,应用程序可以为那些已经接受系统提供的任何“默认”行为的线程更改未捕获异常的处理方式(例如记录到特定设备或文件)。”

你可能会在那里找到问题的答案……好运!: -)

使用Thread.UncaughtExceptionHandler。

Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread th, Throwable ex) {
        System.out.println("Uncaught exception: " + ex);
    }
};
Thread t = new Thread() {
    @Override
    public void run() {
        System.out.println("Sleeping ...");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println("Interrupted.");
        }
        System.out.println("Throwing exception ...");
        throw new RuntimeException();
    }
};
t.setUncaughtExceptionHandler(h);
t.start();

Exception handling in Thread : By default run() method doesn’t throw any exception, so all checked exceptions inside the run method has to be caught and handled there only and for runtime exceptions we can use UncaughtExceptionHandler. UncaughtExceptionHandler is an interface provided by Java to handle exceptions in a Thread run method. So we can implement this interface and set back our implementing class back to Thread object using setUncaughtExceptionHandler() method. But this handler has to be set before we call start() on the tread.

如果我们不设置uncaughtExceptionHandler,那么线程线程组就会充当一个处理程序。

 public class FirstThread extends Thread {

int count = 0;

@Override
public void run() {
    while (true) {
        System.out.println("FirstThread doing something urgent, count : "
                + (count++));
        throw new RuntimeException();
    }

}

public static void main(String[] args) {
    FirstThread t1 = new FirstThread();
    t1.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
        public void uncaughtException(Thread t, Throwable e) {
            System.out.printf("Exception thrown by %s with id : %d",
                    t.getName(), t.getId());
            System.out.println("\n"+e.getClass());
        }
    });
    t1.start();
}
}

http://coder2design.com/thread-creation/#exceptions给出了很好的解释

请看看Thread。UncaughtExceptionHandler

更好的(替代)方法是使用Callable和Future来获得相同的结果…