在实际开发中,经常需要在程序中打开一些物理资源,如数据库连接、网络连接、磁盘文件等,打开这些物理资源之后必须显式关闭,否则将会引起资源泄漏。

JVM的垃圾回收机制不会回收这些资源,垃圾回收机制属于Java内存管理的一部分,它只是负责回收堆内存中分配出来的内存,至于程序中打开的物理资源,垃圾回收机制是无能为力的。

为了正常关闭程序中打开的物理资源,应该使用finally块来保证回收。

下面程序示范了常见的数据库资源。

importjava.sql.Connection;

importjava.sql.DriverManager;

importjava.sql.PreparedStatement;

importjava.sql.ResultSet;

importjava.sql.SQLException;

public class Tester {

public static void main(String[] args) {

String url = "jdbc:mysql://localhost:3306/test";

String user = "root";

String password = "root";

Connection conn = null;

PreparedStatement pst = null;

ResultSet rs = null;

try {

Class.forName("com.mysql.jdbc.Driver");

conn = DriverManager.getConnection(url,user, password);

pst = conn.prepareStatement("select* from test");

rs = pst.executeQuery();

while (rs.next()) {

System.out.println(rs.getObject(0));

}

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

} finally {

try {

rs.close();

pst.close();

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

}

虽然程序已经使用finally块来保证资源被关闭,但是这个程序的关闭是不安全的。因为程序开始时指定conn = null;pst = null;rs = null;,完全有可能在程序运行过程中初始化conn之前就引发了异常,那么conn、pst、rs还未来得及初始化,因此它们根本无需关闭。

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

importjava.sql.Connection;

importjava.sql.DriverManager;

importjava.sql.PreparedStatement;

importjava.sql.ResultSet;

importjava.sql.SQLException;

public class Tester {

public static void main(String[] args) {

String url = "jdbc:mysql://localhost:3306/test";

String user = "root";

String password = "root";

Connection conn = null;

PreparedStatement pst = null;

ResultSet rs = null;

try {

Class.forName("com.mysql.jdbc.Driver");

conn = DriverManager.getConnection(url,user, password);

pst = conn.prepareStatement("select* from test");

rs = pst.executeQuery();

while (rs.next()) {

System.out.println(rs.getObject(0));

}

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

} finally {

try {

if(rs != null){

rs.close();

}

if(pst != null){

pst.close();

}

if(conn != null){

conn.close();

}

} catch (SQLException e) {

e.printStackTrace();

}

}

}

}

程序首先保存rs不为null才关闭,再保证pst不为null才关闭pst,再保证conn不为null才关闭conn。

这样表面看起来安全,实际上并不是这样。假如程序开始已经正常初始化了conn、pst、rs,在关闭rs时出现了异常,那么程序将在关闭rs时非正常退出,这样就会导致pst、conn得不到关闭,从而导致资源泄漏。

为了保证关闭各资源时出现的异常不会相互影响,应该在关闭每个资源时分开使用try...catch块来保证关闭操作不会导致程序非正常退出。

importjava.sql.Connection;

importjava.sql.DriverManager;

importjava.sql.PreparedStatement;

importjava.sql.ResultSet;

importjava.sql.SQLException;

public class Tester {

public static void main(String[] args) {

String url = "jdbc:mysql://localhost:3306/test";

String user = "root";

String password = "root";

Connection conn = null;

PreparedStatement pst = null;

ResultSet rs = null;

try {

Class.forName("com.mysql.jdbc.Driver");

conn = DriverManager.getConnection(url,user, password);

pst = conn.prepareStatement("select* from test");

rs = pst.executeQuery();

while(rs.next()) {

System.out.println(rs.getObject(0));

}

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

} finally {

if (rs != null) {

try {

rs.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if (pst != null) {

try {

pst.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if (conn != null) {

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

}

}

上面程序所示的资源关闭方式才是比较安全的,这种关闭方式主要保证如下3点:

1. 使用finally块来关闭物理资源,保证关闭操作总是会被执行;

2. 关闭每个资源之前首先保证引用该资源的引用变量不为null;

3. 为每个物理资源使用单独try...catch块关闭资源,保证关闭资源时引发的异常不会影响其他资源的关闭。

 转载:http://blog.csdn.net/leaderman_it/article/details/7445491
 

Java正常关闭资源的方式的更多相关文章

  1. Java异常关闭资源的两种方式

    try-catch-finally 常用,在异常关闭时应判断流是否为空 public class CloseableUtils { public static void closeable(Close ...

  2. Effective java 系列之更优雅的关闭资源-try-with-resources

    背景: 在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制,如果我们不在 ...

  3. Java进阶知识点:更优雅地关闭资源 - try-with-resource

    一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制, ...

  4. Java进阶知识点3:更优雅地关闭资源 - try-with-resource及其异常抑制

    一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制, ...

  5. java关闭资源,自制关闭资源工具类

    在网上看到一篇关于关闭资源的正确方式:http://blog.csdn.net/bornforit/article/details/6896775 该博文中的总结: (1)使用finally块来关闭物 ...

  6. Java自学-I/O 关闭流的方式

    关闭流的方式 所有的流,无论是输入流还是输出流,使用完毕之后,都应该关闭. 如果不关闭,会产生对资源占用的浪费. 当量比较大的时候,会影响到业务的正常开展. 步骤 1 : 在try中关闭 在try的作 ...

  7. 数据库连接工具类——包含取得连接和关闭资源 ConnUtil.java

    package com.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepare ...

  8. java7增强的try语句关闭资源

    java7增强的try语句关闭资源 传统的关闭资源方式 import java.io.FileInputStream; import java.io.FileOutputStream; import ...

  9. 更优雅地关闭资源 - try-with-resource及其异常抑制

    原文:https://www.cnblogs.com/itZhy/p/7636615.html 一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在 ...

随机推荐

  1. php生成二维码的插件phpqrcode

    参考网址: http://www.thinkphp.cn/topic/7749.html http://blog.csdn.net/stxyc/article/details/44650971 php ...

  2. IDEA中如何使用Maven进行打包。 IDEA版本是14

    说实话,找了好半天的资料,也许是我的IDEA版本太高了网上资料稀缺,所以愣是没有找到打包的方法,只是自己瞎琢磨了,还好搞出来了,记录一下. 说文字说一下大概流程,其实很简单: 创建配置文件->创 ...

  3. ZooKeeper使用原理

    ZooKeeper的基本原理 ZNode的基本概念 ZooKeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称做一个ZNode.每个ZNode都可以通过其路径唯一标识 ...

  4. The constructor BASE64Encoder() is not accessible due to restriction on required

    在Eclipse中编写Java代码时,用到了BASE64Decoder,import sun.misc.BASE64Decoder;可是Eclipse提示: Access restriction : ...

  5. 使用Expression做Linq的參數化排序

    Linq非常的好用,減少大量的資料庫操作手序,使用具名的類別,減少了在程式中寫SQL寫錯字的可能性,問題來了,如果我想用QueryString中的參數,作為排序的依據,但是因為是具名的類別,不能指定字 ...

  6. ASP.NET后台JS弹框使前台页面样式丢失 解决办法

    Response.Write("<script>alert('您还没有上传相关图片!');</script>");是向前台输出js 应该用下面的方法 Cli ...

  7. Spring动态配置多数据源

    Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性.而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时 ...

  8. html ul 里 能放其他标签吗,比如h3、p?

    按标准的话,ul 里面应该只能放li,不过看见同事有的放了h3.p这些,这样到底可不可以?   <ul>里面只能放<li>.但是<li>里面可以放<h*> ...

  9. IIS浏览提示无法显示网页的解决方法

    1.错误号401.1 症状:HTTP 错误 401.1 - 未经授权:访问由于凭据无效被拒绝. 分析: 由于用户匿名访问使用的账号(默认是IUSR_机器名)被禁用,或者没有权限访问计算机,将造成用户无 ...

  10. rsync服务器的配置和使用

    yum install -y rsyncuseradd rsync -s /sbin/nologinmkdir /backupmkdir /backup1 chown rsync:rsync /bac ...