捕获程序整体的终止时

未捕获的异常的处理器

假设程序抛出异常时,并没有编写捕获该异常的catch语句块。通常情况下,这么做会导致程序在输出线程的调用堆栈信息后终止。
如果使用Thread类的setDefaultUncaughtedExceptionHandler静态方法,可以设置未捕获的异常的处理器(Uncaught Exception Handler)。该处理器是Thread.UncaughtExceptionHandler接口类型的对象,实际的处理编写在uncaughtException方法中。设置了未捕获的异常的处理器后,程序将不会输出调用堆栈而是直接终止。

退出钩子

退出钩子(Shutdown Hook)是指在Java虚拟机退出时启动的线程。“Java虚拟机退出时”指的是System.exit()被调用或是全部非守护线程终止时。这时可以使用退出钩子来编写程序完全终止时的终止处理。
可以使用java.lang.Runtime类的实例方法addShutdownHook来设置退出钩子。

Main.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class Main {

public static void main(String[] args) {
System.out.println("main:BEGIN");

Thread.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable exception) {
System.out.println("****");
System.out.println("UncaughtExceptionHandler:BEGIN");
System.out.println("currentThread = " + Thread.currentThread());
System.out.println("thread = " + thread);
System.out.println("exception = " + exception);
System.out.println("UncaughtExceptionHandler:END");
}
});

Runtime.getRuntime().addShutdownHook(
new Thread() {
@Override
public void run() {
System.out.println("****");
System.out.println("shutdown hook:BEGIN");
System.out.println("currentThread = " + Thread.currentThread());
System.out.println("shutdown hook:END");
}
}
);

new Thread("MyThread") {
@Override
public void run() {
System.out.println("MyThread:BEGIN");
System.out.println("MyThread:SLEEP...");

try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}

System.out.println("MyThread:DIVIDE");
int x = 1 / 0;

System.out.println("MyThread:END");
}
}.start();

System.out.println("main:END");
}
}

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
main:BEGIN
main:END
MyThread:BEGIN
MyThread:SLEEP...
MyThread:DIVIDE
****
UncaughtExceptionHandler:BEGIN
currentThread = Thread[MyThread,5,main]
thread = Thread[MyThread,5,main]
exception = java.lang.ArithmeticException: / by zero
UncaughtExceptionHandler:END
****
shutdown hook:BEGIN
currentThread = Thread[Thread-0,5,main]
shutdown hook:END