转自:http://hi.baidu.com/litertiger/blog/item/507675f0483bf2aba40f52c7.html
Runtime的(当Java程序非法退出时,这个可以用来在写日志等操作,免得推出的时候,不知道自己运行到什么地方,或者是假死机状态的时候,调用强制结束的时候用)
addShutdownHook
public void addShutdownHook(Thread hook)
-
注册新的虚拟机来关闭挂钩。
Java 虚拟机会为了响应以下两类事件而关闭:
- 程序正常退出,这发生在最后的非守护线程退出时,或者在调用
exit
(等同于System.exit
)方法时。或者, - 为响应用户中断而终止 虚拟机,如键入 ^C;或发生系统事件,比如用户注销或系统关闭。
关闭挂钩 只是一个已初始化但尚未启动的线程。虚拟机开始启用其关闭序列时,它会以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行。运行完所有的挂钩后,如果已启用退出终结,那么虚拟机接着会运行所有未调用的终结方法。最后,虚拟机会暂停。注意,关闭序列期间会继续运行守护线程,如果通过调用
exit
方法来发起关闭序列,那么也会继续运行非守护线程。一旦开始了关闭序列,则只能通过调用
halt
方法来停止这个序列,此方法可强行终止虚拟机。一旦开始了关闭序列,则不可能注册新的关闭挂钩或取消注册先前已注册的挂钩。尝试执行这些操作会导致抛出
IllegalStateException
。关闭挂钩可在虚拟机生命周期中的特定时间运行,因此应保护性地对其进行编码。特别是应将关闭挂钩编写为线程安全的,并尽可能地避免死锁。关闭挂钩还应该不盲目地依靠某些服务,这些服务可能已注册了自己的关闭挂钩,所以其本身可能正处于关闭进程中。
关闭挂钩应该快速地完成其工作。当程序调用
exit
时,虚拟机应该迅速地关闭并退出。由于用户注销或系统关闭而终止虚拟机时,底层的操作系统可能只允许在固定的时间内关闭并退出。因此在关闭挂钩中尝试进行任何用户交互或执行长时间的计算都是不明智的。与其他所有线程一样,通过调用线程
ThreadGroup
对象的uncaughtException
方法,可在关闭挂钩中处理未捕获的异常。此方法的默认实现是将该异常的堆栈跟踪 (stack trace) 打印至System.err
并终止线程;它不会导致虚拟机退出或暂停。仅在很少的情况下,虚拟机可能会中止,也就是没有完全关闭就停止运行。虚拟机被外部终止时会出现这种现象,比如在 Unix 上使用 SIGKILL 信号或者在 Microsoft Windows 上调用 TerminateProcess。如果由于内部数据结构损坏或试图访问不存在的内存而导致本机方法执行错误,那么可能也会中止虚拟机。如果虚拟机中止,则无法保证是否将运行关闭挂钩。
-
参数:
-
hook
- 一个已初始化但尚未启动的Thread
对象
抛出:
-
IllegalArgumentException
- 如果指定的挂钩已注册,或者可以确定挂钩正在运行或者已运行完毕 -
IllegalStateException
- 如果虚拟机已经处于关闭进程中 -
SecurityException
- 如果安全管理器存在并且拒绝RuntimePermission
("shutdownHooks")
-
例子程序:
public class ShutdownDemo {
public ShutdownDemo ( ) {
Thread t = new ShutdownHookThread ( “Here I am !!!” );
Runtime.getRuntime().addShutdownHook ( t );
System.out.println ( “Now shut me down …” );
while ( true ) {
System.out.print ( “.” );
try {
Thread.sleep ( 300 );
} catch ( InterruptedException ie ) { }
}}
public static void main ( String args[] ) {
new ShutdownDemo ( );
}}
class ShutdownHookThread extends Thread {
protected String message;
public ShutdownHookThread ( String message ) {
this.message = message;
}public void run ( ) {
System.out.println ( );
System.out.println ( message );
}}
Runtime.getRuntime().addShutdownHook(Thread);
//addShutdownHook是指,增加JVM停止时要做处理事件。当JVM停止时,就会把之前增加的这些HOOK逐个运行。
运行这个例子可以简单体会到它的作用.
package Thread;
public class Thread1 extends Thread{
public void run() {
int i=0;
while(i<10){
try {
Thread.sleep(2000);
}
catch (InterruptedException ex) {
}
System.out.println("~Thread 1~");
i++;
}
}
}
package Thread;
public class Thread2 extends Thread{
public void run() {
int i=0;
while(i<10){
try {
Thread.sleep(1000);
}
catch (InterruptedException ex) {
}
System.out.println("~Thread 2~");
i++;
}
}
}
package Thread;
public class Thread3 extends Thread{
public void run(){
System.out.println("---end---");
}
}
package Thread;
public class addShutdownHookTest{
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread3());
Thread1 t1 = new Thread1();
t1.start();
Thread2 t2 = new Thread2();
t2.start();
}