public class TestExceptionThread {
public static void main(String args[]) {
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new ExceptionThread());
}
}
class ExceptionThread implements Runnable {
public void run () {
throw new RuntimeException();
}
}
毫无疑问,这段代码执行的时候肯定会报错。异常信息如下:
Exception in thread "pool-1-thread-1" java.lang.RuntimeException
at ExceptionThread.run(TestExceptionThread.java:13)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
于是,我们将代码做一下改动,添加一个try ... catch试试,改动如下:
public class TestExceptionThread {
public static void main(String args[]) {
ExecutorService exec = Executors.newCachedThreadPool();
try {
exec.execute(new ExceptionThread());
} catch (RuntimeException e) {
System.out.println("Exception has been handler");
}
}
}
public class TestExceptionThread {
public static void main(String args[]) {
try {
Thread t = new Thread(new ExceptionThread());
t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
t.start();
} catch (RuntimeException e) {
System.out.println("Exception has been handler");
}
}
}
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("got unCaughtException");
}
}
class ExceptionThread implements Runnable {
@Override
public void run () {
throw new RuntimeException();
}
}
输出结果是
got unCaughtException
但是,如果我们将main(String args[])方法中的内容改成这样:
public static void main(String args[]) {
ExecutorService exec = Executors.newCachedThreadPool();
Thread t = new Thread(new ExceptionThread());
t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
exec.execute(t);
}
发现运行结果会是这样:
Exception in thread "pool-1-thread-1" java.lang.RuntimeException
at ExceptionThread.run(TestExceptionThread.java:31)
at java.lang.Thread.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
public class TestExceptionThread {
public static void main(String args[]) {
ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
Thread t = new Thread(new ExceptionThread());
exec.execute(t);
}
}
class HandlerThreadFactory implements ThreadFactory{
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
System.out.println("Create thread t");
t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
System.out.println("eh=" + t.getUncaughtExceptionHandler());
return t;
}
}
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("got unCaughtException");
}
}
class ExceptionThread implements Runnable {
@Override
public void run () {
System.out.println("eh=" + Thread.currentThread().getUncaughtExceptionHandler());
throw new RuntimeException();
}
}
运行结果如下:
Create thread t
eh=MyUncaughtExceptionHandler@10d448
eh=MyUncaughtExceptionHandler@10d448
got unCaughtException
第三种方式
我们可以采用在Thread类中设置一个静态域,代码如下:
public class TestExceptionThread {
public static void main(String args[]) {
Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
Thread t = new Thread(new ExceptionThread());
t.start();
}
}
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("got unCaughtException");
}
}
class ExceptionThread implements Runnable {
@Override
public void run () {
throw new RuntimeException();
}
}
在
Android
开发中,由于生产环境的复杂性,各种各样的问题难免会造成App的Crash。为此,我们通常需要定义一个CrashHandler来从全局的角度去捕获各种异常。Android
开发中,从功能来说有两种类型的线程,主线程(UI线程)和子线程。由于线程的本质特性,我们不能捕获从线程中逃逸出来的异常,一旦异常逃出任务的run()方法,便会向外传播。如下:毫无疑问,这段代码执行的时候肯定会报错。异常信息如下:
于是,我们将代码做一下改动,添加一个
try ... catch
试试,改动如下:运行程序,运行的结果和上面一下,异常信息还是没有捕获到。
此时,就该用
Thread.UncaughtExceptionHandler
了。它是Java SE5
中提供的一个接口,允许在每个Thread
对象上附着一个异常处理器,该接口中的uncaughtException()
方法会在线程因未捕获到的异常而临近死亡前被调用。第一种方式
代码如下:
输出结果是
但是,如果我们将
main(String args[])
方法中的内容改成这样:发现运行结果会是这样:
也就是说: 如果这样写,线程中的异常还是没有捕捉到。
第二种方式
ThreadFactory
来创建线程,并为创建的线程指定uncaughtExceptionHandler.运行结果如下:
第三种方式
我们可以采用在Thread类中设置一个静态域,代码如下:
同样会发现,异常会捕捉到。需要注意一点是这个处理器只有在不存在线程专有的末捕获异常处理器的情况下才会被调用。系统会检查线程专有版本,如果没有发现,则检查线程组是否有其专有的uncaughtException()方法,如果也没有,再调用defaultUncaughtExceptionHandler。
Java 编程思想(第4版)P642-P644
Thread.UncaughtExceptionHandler在Android中的应用
CrashHandler
如下:完成