销毁bean

  1)执行某一方法如destroy()方法,然后在<bean>标签上的destroy-method属性制定方法名就行。2)实现DisopableBean接口的destroy方法,DispoableBean接口只有一个destroy方法,在bean销毁前调用

public class DestructiveBeanImpl implements DisposableBean{
        public void destroy(){
            //System.out.println("销毁bean");//计入日志等代码
        }
}

  3)关闭钩子shutdownHook来进行销毁Bean。Spring销毁回调的唯一确定是他们不能被自动出发,得在应用关闭之前调用destroySingletons()方法。在java中允许创建一个关闭钩子,一个刚好在应用关闭前会被执行的一个线程。这是一个调用BeanFactory的destroySingletons方法的最佳途径。创建一个实现了Runnable接口的类,并在run()方法中调用destroySingletons()。代码清单如下:

  通过Runtime实例,使得应用程序和其运行环境相连接。Runtime是在应用启动期间自动建立,应用程序不能够创建Runtime,但是可以通过Runtime.getRuntime()来获得当前应用的Runtime对象引用,通过该引用我们可以获得当前运行环境的相关信息,比如空闲内存、最大内存以及为当前虚拟机添加关闭钩子(addShutdownHook()),执行指定命令(exec())等。

  jvm的关闭方式有三种
  正常关闭:当最后一个非守护线程结束或者调用System.exit或者通过其他特定平台的方法关闭(发送SIGINT,SIGTERM信号等)
  强制关闭:通过调用Runtime.halt方法或者是在操作系统中直接kill(发送SIGKILL信号)掉JVM进程
  异常关闭:运行中遇到RuntimeException异常等。
  特别注意的是:如果JVM因异常关闭,那么子线程(Hook本质上也是子线程)将不会停止。但在JVM被强行关闭时,这些线程都会被强行结束。关闭钩子本质是一个线程(也称为Hook线程),用来监听jvm的关闭。通过Runtime的addShutdownHook可以向JVM注册一个关闭钩子。Hook线程在JVM正常关闭才会执行,强制关闭时不会执行。

       JVM中注册的多个关闭钩子是并发执行的,无法保证执行顺序,当所有Hook线程执行完毕,runFinalizersOnExit为true,JVM会先运行终结器,然后停止。

       利用addShutdownHook优雅的关闭线程

    private static ThreadPoolExecutor THREAD_POOL;

    private static final int MAX = 8;

    static {
        int max = Runtime.getRuntime().availableProcessors();
        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(200);
        RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.CallerRunsPolicy();

        THREAD_POOL = new ThreadPoolExecutor(1, max > MAX ? MAX : max, 60L, TimeUnit.SECONDS, queue, rejectedExecutionHandler);
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            // 使新任务无法提交.
            THREAD_POOL.shutdown();

            try {
                // 等待5秒如果还没有关闭,则强制关闭
                if (THREAD_POOL.awaitTermination(5L, TimeUnit.SECONDS)) {
                    THREAD_POOL.shutdownNow();
                }
            } catch (InterruptedException e) {
                log.error("线程关闭异常", e);
                Thread.currentThread().interrupt();
                THREAD_POOL.shutdownNow();
            }
        }));
    }

  

 

  

  

  

  

posted on 2022-06-10 17:15  溪水静幽  阅读(311)  评论(0)    收藏  举报