`
cy729215495
  • 浏览: 129250 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

对流关闭的一点认识

阅读更多

1.创建的流一定要有引用,便于回收.比如通过某个方法得到的流如果直接当成参数传递了就不能关闭了;
 比如f()函数返回InputStream,而 f1(InputStream); 我们不能就f1(f()),这样流就不能关闭了.

 

 

2.使用流一定要连续使用,举个例子,InputStream in=f.getInputStream();很可能我们的这个方法得到的流已经关闭了,但是对象依然存在内存里面,这个时候如果我们再用in去做读写操作,就会报流关闭的错误了.

 

在举个更具体点的例子,在a类里面我们可能给b类设置了流,并且关闭了,在c类里面要用b类的流去读写,这个时候就出问题了,因为流已经关闭了,所以在c类想用流做的一些事情就直接在a类里面做了,在关闭流这样就不会出现问题了

 

 

第二点尤其要注意,于此类似的还有数据库的连接,socket,也是一样的道理,因为这些资源跟普通的java类是不一样的,内存和文件,内存和数据库它是有一根隐形的"带子"连在一起,而其他的类没有,自己的感悟而已,跟大家分享一下,如有错误,请多指点

分享到:
评论
15 楼 llade 2008-12-18  
流和数据库连接这类系统资源有两个特点,一个是有限性,二独占性。所以这类资源被占用的时间应该尽可能短,而数据库连接池这类被池化的对象还有另外一层原因,创建资源过程消耗时间或空间过多。对象的生命周期基本上都是create-->ready-->serve(maybe many time)-->destroy,对于我们来说serve的过程是最重要的,如果对象是无状态的,则可以多线程共享,如果是有状态的或者提供的数据是不可分割的(事务的),则为每个线程服务完毕之后,需要置为ready状态才可为下个线程服务。我们需要增强的是ready-->serve这段,最坏的情况就是不能线程共享的对象要长时间的服务,假如事务的不可分割,需要长时间占用资源对象的serve时间,这就要需要协作对象之间有某种默契,谁创建谁关闭则是一种默契了,而另置一个事务控制器(通常是AOP织入)也是一种默契,前者是创建者兼任了事务控制器,有时候事务资源夸的调用太多了,那事务资源通常都会某种包装,比如创建者把资源包装起来,除了创建者本身,不能destroy资源(或者将资源重置ready状态),对于使用过Proxy模式的人来说这再熟悉不过了,这里有个陷阱就是创建者忘记关闭资源了,需要有个测试机制对其进行补漏,而事务控制器则不易出现这方面的缺陷。
还有的系统,事务设计是可分段提交的,或快速失败的,或乐观锁机制等等手段。无它,都是为了避免人脑(程序员)的出错(概率很高哦,风险也高)。
14 楼 cuiyi.crazy 2008-12-18  
系统对资源的回收永远不是及时的;
如果不自己manually关闭,可能潜在的隐患会不少
13 楼 memorymyann 2008-12-16  
大家是如何理解为什么流需要自己手动关闭,而不是靠垃圾回收器或者操作系统来回收的???
12 楼 sdh5724 2008-12-11  
楼上的, POOL的东西, 不是应用本身建立的, 这个东西可以理解为pool自己创建的。
11 楼 fjlyxx 2008-12-10  
系统是几十万人用,同一时间并发几个。如果你的系统是一个SOA平台中的转发节点(和路由器一样的) 同一时间压力的话你怎么办?  我不是反对谁创建谁关闭,我只是想说明一点,水位保护是一个让你系统更健壮的东西,不要排斥它。
简单的说,你的WEB服务器,你能想让几个人连接就有几个人连接吗?

假如你的数据库支持同一时间最多100个会话,按你的想法谁创建谁关闭,那么当同时并发超过100个的时候你怎么办? 你怎么去做你的等待机制,再者,你怎么去很好知道我创建了的连接就 能被正确关闭,如果你的系统没问题,而数据库出问题了。你又如何提高你系统的容错能力。

我只是在设计的角度提出一种我认为比较可行的方案。
10 楼 cy729215495 2008-12-10  
我们自己写的数据库连接池都是用了然后显示的调用close来关闭的,我们的系统是几十万人用都没有出现过数据库崩溃的现象.谁创建谁关闭,就是这个原则.
9 楼 fjlyxx 2008-12-09  

难道我们当我们遇到连接数不够的时候能将性能问题归结于我们用了连接池?

这个问题你要感谢连接池,如果没有连接池的保护,你的数据库可能会挂掉。

这个就是我说的水位保护问题。
8 楼 czx566 2008-12-09  
数据库连接池应该就是这个原则的体现

难道我们当我们遇到连接数不够的时候能将性能问题归结于我们用了连接池?


针对你说的
如果,你这个流是一个存活在多线程的环境中,你会怎么解决这个水位问题。

我认为不管这个流在哪种环境下,如果你不用了,你必须及时归还你的引用,关不关你就别操心了!

这个不违背 谁分配,谁释放的原则。
7 楼 fjlyxx 2008-12-09  
OK  说说我的看法。
第一 谁分配的问题。你把分配权限公布出去,那么是不是谁都可以分配。那么你这个水位你控制。


第二 谁释放的问题。比你更高层的调用者怎么知道你什么时候会释放。

如果,你这个流是一个存活在多线程的环境中,你会怎么解决这个水位问题。
6 楼 czx566 2008-12-09  
楼上的,还是有点想不通~


我觉得如果压力大,不能将其归结于 谁分配, 谁释放的原则。

希望能有更详细的例举~~~




5 楼 fjlyxx 2008-12-09  
谁分配, 谁释放,对于小系统是适合的,但是如果资源有限,系统压力大的情况下 水位不容易控制。这时候这种就不适用了。
4 楼 czx566 2008-12-09  
楼上的为什么这个原则不赞同?

我倒想听听
3 楼 sdh5724 2008-12-08  
其实这个道理跟C++内存分配与释放道理很相似。

楼上说的用封装来保证, 也是一个办法, 但是未免要求也过于高, 很多一般的程序员是很难做到的。

C++, 我以前的处理原则就是 谁分配, 谁释放。 我想对于资源, 都可以使用类似办法。  ---见笑了, 这个原则很多人不赞同的。

2 楼 fjlyxx 2008-12-08  
建议看看MINA的框架,好的框架会把流封装的很好,对于SOCKET来说寻找一个统一的领域是很容易的 因为在你的业务中都可以用BYTE[]进行传递。

比如A B C D四个业务节点,A是进行解压的B是进行解密的C是业务逻辑D是其他什么操作。
在这个流程中完全可以通过BYTE[]进行传递。这个是横向的设计。
纵向而言,SOCKET完全可以把它解收到的数据塞到业务中(应用回掉就是了),这样方便统一管理SOCKET,对于业务SOCKET不暴露,可以保证俩连接安全。
1 楼 bloodrate 2008-12-08  
Stream这样的东西,能不传递就尽量不要传递,和包含瞬时状态的对象少传递为妙,比如Socket,Socket.getInputStream传递给其他方法,Socket close掉了,Stream自然close掉了
Global site tag (gtag.js) - Google Analytics