try块的finally块没有被执行

111 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情

前言

兄弟们,这漫长的一周终于结束了,今天真的是身在曹营心在汉的感觉哈哈哈哈

学习方面,今天结合昨天学的System.exit(),来理解一下这个问题,同时加深对其的理解;

梳理

public class shutDownHooksDemo {
    public static void main(String[] args) {
        for(int i=0;i<5;i++)
        {
            try {
                if(i==4) {
                    System.out.println("Inside Try Block.Exiting without executing Finally block.");
                    System.exit(0);
                }
            }
            finally {
                System.out.println("Inside Finally Block.");
            }
        }
    }
}

从上述代码可以看到,finally块中的语句应该会被执行5次,但是实际运行后发现,fianlly块只执行了4次;

其实是在第5次迭代的时候会触发exit函数的调用,这个昨天我们学习过了,原因便是——System.exit会挂起所有线程的执行,包括当前线程。即便是try语句后的finally块,只要是执行了exit,便也无力回天了。

在调用System.exit时,JVM会在关闭前执行两个结束任务:

首先,它会执行完所有通过Runtime.addShutdownHook注册进来的终止的钩子程序。这一点很关键,因为它会释放JVM外部的资源。

接下来的便是Finalizer,可能是System.runFinalizersOnExit也可能Runtime.runFinalizersOnExit。finalizer的使用已经被废弃有很长一段时间了。finalizer可以在存活对象上进行调用,即便是这些对象仍在被其它线程所使用。而这会导致不可预期的结果甚至是死锁。

可以改成下面这种方式: image.png

综述

作为开发者的我们,经常会遇到各种各样的问题,有些是基础语法写错了、配置忘记配了或者不匹配了、对有深度的一些语法和框架之类的理解不够到位就贸然使用了等等;但是我觉得首先要正视各种问题,心态一定要放平稳;先梳理好其中的逻辑,再一点一点地仔细排查,多向前辈们请教,然后这些经验就会成为我们宝贵的财富;共勉~