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)

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


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

  • 相关阅读:
    31 把数组排成最小的数 + 仿函数的写法就记忆这个就行了
    30 整数中1出现的次数(从1到n整数中1出现的次数)这题很难要多看*
    29 连续子数组的最大和
    c/c++ struct的大小以及sizeof用法
    28 最小的K个数
    27 数组中出现次数超过一半的数字
    26 字符串的排列
    Python 实例2—购物车
    python_threading模块实现多线程详解(转)
    Ubuntu 16.04 安装Postman
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7271972.html
Copyright © 2011-2022 走看看