zoukankan      html  css  js  c++  java
  • JAVA虚拟机关闭钩子(Shutdown Hook)

    Java程序常常也会遇到进程挂掉的情况。一些状态没有正确的保存下来,这时候就须要在JVM关掉的时候运行一些清理现场的代码。JAVA中的ShutdownHook提供了比較好的方案。

    JDK提供了Java.Runtime.addShutdownHook(Thread hook)方法。能够注冊一个JVM关闭的钩子。这个钩子能够在一下几种场景中被调用:

    1. 程序正常退出
    2. 使用System.exit()
    3. 终端使用Ctrl+C触发的中断
    4. 系统关闭
    5. OutOfMemory宕机
    6. 使用Kill pid命令干掉进程(注:在使用kill -9 pid时,是不会被调用的)
    以下是JDK1.7中关于钩子的定义:

        public void addShutdownHook(Thread hook)
    參数:
        hook - An initialized but unstarted Thread object 
    抛出: 
        IllegalArgumentException - If the specified hook has already been registered, or if it can be determined that the hook is already running or has already been run 
        IllegalStateException - If the virtual machine is already in the process of shutting down 
        SecurityException - If a security manager is present and it denies RuntimePermission("shutdownHooks")
    从下面版本号開始: 
        1.3 
    另请參见:
        removeShutdownHook(java.lang.Thread), halt(int), exit(int)

    首先来測试第一种,程序正常退出的情况:

    package com.hook;
    
    import java.util.concurrent.TimeUnit;
    
    public class HookTest
    {
    	public void start()
    	{
    		Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
    			@Override
    			public void run()
    			{
    				System.out.println("Execute Hook.....");
    			}
    		}));
    	}
    	
    	public static void main(String[] args)
    	{
    		new HookTest().start();
    		System.out.println("The Application is doing something");
    		
    		try
    		{
    			TimeUnit.MILLISECONDS.sleep(5000);
    		}
    		catch (InterruptedException e)
    		{
    			e.printStackTrace();
    		}
    	}
    }
    
    执行结果:

    The Application is doing something
    Execute Hook.....
    如上能够看到。当main线程执行结束之后就会调用关闭钩子。

    以下再来測试第五种情况(顺序有点乱,表在意这些细节):

    package com.hook;
    
    import java.util.concurrent.TimeUnit;
    
    public class HookTest2
    {
    	public void start()
    	{
    		Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
    			@Override
    			public void run()
    			{
    				System.out.println("Execute Hook.....");
    			}
    		}));
    	}
    	
    	public static void main(String[] args)
    	{
    		new HookTest().start();
    		System.out.println("The Application is doing something");
    		byte[] b = new byte[500*1024*1024];
    		try
    		{
    			TimeUnit.MILLISECONDS.sleep(5000);
    		}
    		catch (InterruptedException e)
    		{
    			e.printStackTrace();
    		}
    	}
    
    }
    执行參数设置为:-Xmx20M  这样能够保证会有OutOfMemoryError的发生。

    执行结果:

    The Application is doing something
    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    	at com.hook.HookTest2.main(HookTest2.java:22)
    Execute Hook.....
    能够看到程序遇到内存溢出错误后调用关闭钩子。与第一种情况中。程序等待5000ms执行结束之后推出调用关闭钩子不同。

    接下来再来測试第三种情况:

    package com.hook;
    
    import java.util.concurrent.TimeUnit;
    
    public class HookTest3
    {
    	public void start()
    	{
    		Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
    			@Override
    			public void run()
    			{
    				System.out.println("Execute Hook.....");
    			}
    		}));
    	}
    	
    	public static void main(String[] args)
    	{
    		new HookTest3().start();
    		Thread thread = new Thread(new Runnable(){
    
    			@Override
    			public void run()
    			{
    				while(true)
    				{
    					System.out.println("thread is running....");
    					try
    					{
    						TimeUnit.MILLISECONDS.sleep(100);
    					}
    					catch (InterruptedException e)
    					{
    						e.printStackTrace();
    					}
    				}
    			}
    			
    		});
    		thread.start();
    	}
    
    }
    
    在命令行中编译:javac com/hook/HookTest3.java

    在命令行中执行:java com.hook.HookTest3  (之后按下Ctrl+C)

    执行结果:
    能够看到效果如预期。


    还有几种情况就不一一列出了。有兴趣的读者能够试一下。

  • 相关阅读:
    Java学习之路-Hessian学习
    Hessian知识学习总结(二)——Hessian的helloworld
    如何封装RESTful Web Service
    c#string为传值模式
    Acrobat 无法在本页面上执行OCR识别
    redis error It was not possible to connect to the redis server(s); to create a disconnected multiplexer, disable AbortOnConnectFail. SocketFailure on PING
    关于bootstrap的modal弹出层嵌套子Modal所引发的血案(转)
    项目学习——后台事件监听并触发相应操作
    Redis学习笔记
    正则表达式
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7271972.html
Copyright © 2011-2022 走看看