系统遇到System.exit(0);还会执行finally块么?

我们都知道finally块是异常代码块中,必须要被执行的代码,但有一种情况例外,下面看一段程序,尝试打开了一个磁盘输出流,然后使用finally块来关闭这个磁盘输出流

package chapter8;

import java.io.FileOutputStream;
import java.io.IOException;

public class ExitFinally {
	public static void main(String[] args) throws IOException{
		FileOutputStream fos = null;
		try{
			fos = new FileOutputStream("a.bin");
			System.out.println("程序打开物理资源!");
			System.exit(0);
		}
		finally{
			//使用finally块关闭资源
			if(fos!= null){
				try{
					fos.close();
				}
				catch(Exception e){
					e.printStackTrace();
				}
			}
			System.out.println("程序关闭了物理资源");
		}
	}
}
这个程序与前面遇到的程序略有不同的是,程序中try块中增加了System.exit(0);来退出程序。程序在执行System.exit(0)后,finally块是否还会执行的机会的呢?尝试运行上面的程序,会看到程序有时并不会执行finally块的代码块。

不论try块是正常结束,还是中途非正常退出,finally块确实都会执行。然而在这个程序中,try语句根本就没有结束其执行过程,System.exit(0);将停止当前线程和所有其他当场死亡的线程。finally块并不能让已经停止的线程继续执行。

当System.exit(0)被调用时,虚拟机退出当前要执行两项清理工作。

1、执行系统中注册的所有关闭钩子。

2、如果程序调用了System.runFinalizerOnExit(true);,那么JVM会对所有的还未结束的对象调用Finalizer。

第二种方式已经被证明是极度危险的,因此JDK  API文档中说明第二种方式已经过时了,因此实际开发中不应该使用这种危险的行为。

第一种方式则是一种安全的操作,系统可以将关闭资源的操作注册成为关闭钩子。在JVM退出之前,这些关闭钩子将会被调用,从而保证物理资源正常关闭。

可以将上面的程序改为如下形式:

package chapter8;

import java.io.FileOutputStream;
import java.io.IOException;

public class ExitHook {
	public static void main(String[] args)throws IOException{
		final FileOutputStream fos;
		fos = new FileOutputStream("a.bin");
		System.out.println("程序打开物理资源!");
		Runtime.getRuntime().addShutdownHook(
				new Thread()
				{
					public void run(){
						//使用关闭钩子来关闭资源
						if(fos != null){
							try{
								fos.close();
							}catch(Exception e){
								e.printStackTrace();
							}
						}
						System.out.println("程序关闭了物理资源");
					}
				}
				);
		System.exit(0);
	}
}
上面的粗体字代码为系统注册了一个关闭钩子,关闭钩子负责在程序退出时回收系统资源,运行上面的程序,将可以看到系统中可以正常关闭的物理资源。


  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网极客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值