持续创作,加速成长!这是我参与「掘金日新计划 · 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可以在存活对象上进行调用,即便是这些对象仍在被其它线程所使用。而这会导致不可预期的结果甚至是死锁。
可以改成下面这种方式:
综述
作为开发者的我们,经常会遇到各种各样的问题,有些是基础语法写错了、配置忘记配了或者不匹配了、对有深度的一些语法和框架之类的理解不够到位就贸然使用了等等;但是我觉得首先要正视各种问题,心态一定要放平稳;先梳理好其中的逻辑,再一点一点地仔细排查,多向前辈们请教,然后这些经验就会成为我们宝贵的财富;共勉~