博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
由close引发的故事
阅读量:6684 次
发布时间:2019-06-25

本文共 2267 字,大约阅读时间需要 7 分钟。

hot3.png

最近在写一些多线程的任务,有时候任务处理多起来,一些不好的编程毛病就变得恐惧起来。

1. 采用框架,在读取信息时候有些慢,于是我用原生jdbc来完成的。代码如下:

public List
getIsbns(int offset, int size) { try { Connection con = dataSource.getConnection(); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("select pisbn from amazon_book where flag is null limit " + offset + ", " + size); List
list = new ArrayList
(size); while (rs.next()) { list.add(rs.getString(1)); } return list; } catch (SQLException e) { e.printStackTrace(); } return null; }

由于,我没有及时的关闭Connection,导致程序在运行不久后出现了问题。

情况描述:

1. 采用直连方式,每次都需要创建连接,而连接又未释放,导致保持过多数据库连接资源,数据查询结果响应降低。
2. 采用数据库连接池方式,由于没有及时释放资源,导致数据库连接池达到最大的时候,使得其他数据库请求等待,导致数据库访问有一种静默的样子。

查看java.sql.Connection源码,发现有如下注释

/**     * Releases this Connection object's database and JDBC resources     * immediately instead of waiting for them to be automatically released.     * 

* Calling the method close on a Connection * object that is already closed is a no-op. *

* It is strongly recommended that an application explicitly * commits or rolls back an active transaction prior to calling the * close method. If the close method is called * and there is an active transaction, the results are implementation-defined. *

* * @exception SQLException SQLException if a database access error occurs */ void close() throws SQLException;

【我们应该手动释放不应用的资源,而不是等待被自动回收】,如果资源被消耗殆尽,只能等待虚拟机自己去回收了,这样的程序不是高效的。

2. 在字符写入文件时候,对于OutputStream没有及时close

try {		File f = new File(bookFolder + "page.html");		System.out.println(f.getPath());		if (!f.getParentFile().exists()) {			f.getParentFile().mkdirs();		}		if (!f.exists()) f.createNewFile();		IOUtils.copy(new ByteArrayInputStream(doc.toString().getBytes()), new FileOutputStream(f));	} catch (Exception e) {		throw new RuntimeException(e.getMessage(), e);	}

原因:  

操作系统的中打开文件的最大句柄数受限所致,常常发生在很多个并发用户访问服务器的时候.因为为了执行每个用户的应用服务器都要加载很多文件(new一个socket就需要一个文件句柄),这就会导致打开文件的句柄的缺乏.
解决:
尽量把类打成jar包,因为一个jar包只消耗一个文件句柄,如果不打包,一个类就消耗一个文件句柄.
java的垃圾回收不能关闭网络连接打开的文件句柄,如果没有执行close()(例如:java.net.Socket.close())则文件句柄将一直存在,而不能被关闭.你也可以考虑设置socket的最大打开数来控制这个问题.

所以养成良好的编码习惯,在对数据库访问,文件操作完毕后,通过finally模块将其关闭,以免发生不必要的问题。

转载于:https://my.oschina.net/u/161336/blog/272333

你可能感兴趣的文章
ASP.NET 生成图片验证码
查看>>
ToString()转换格式;DateTime.ToString()用法详解
查看>>
如何让Apache不显示服务器信息
查看>>
VSS配置
查看>>
数据分页存储过程
查看>>
事件流
查看>>
HDU-1532-Drainage Ditches
查看>>
angularJS的学习资源,巨全
查看>>
计算最长英语单词链
查看>>
LIS和LCS算法分析
查看>>
Error prompt:“xxx is not in the sudoers file”----Solution
查看>>
基于Silverlight的新浪微博客户端 - LightBus
查看>>
C#多维数组与嵌套数组
查看>>
Sublime text3的一些操作
查看>>
MySQL-ProxySQL中间件(二)| Admin Schemas介绍
查看>>
Python 设置 IP 代理 访问网页 ( 用户名密码验证代理 )
查看>>
从点云中提取杆状物算法
查看>>
sqlplus用户登录
查看>>
更轻松的获取APK文件安装时间
查看>>
Web标准中用于改善Web应用程序性能的各种方法总结
查看>>