Java 理论与实践: 良好的内务处理实践

taosbr0640

taosbr0640

2016-02-19 18:38

今天给大家分享的是由图老师小编精心为您推荐的Java 理论与实践: 良好的内务处理实践,喜欢的朋友可以分享一下,也算是给小编一份支持,大家都不容易啊!

  垃圾收集几乎是每个开发人员都喜爱的一个 Java 平台特性,它简化了开发,消除了所有种类的潜在代码错误。可尽管垃圾收集一般来说可以让您无需进行资源治理,有时候您还是必须自己进行一些内务处理。在本文中,Brian Goetz 讨论了垃圾收集的局限性,并指出了您必须自己做内务处理的场景。
  
  小时候,父母总是叮嘱我们玩了玩具之后要收好。假如您仔细想想,其实这种唠叨并不过分,要保持整洁是因为存在实际的限制,房间里没有太多的空间,假如到处堆满了玩具,那么连走路都无处下脚了。
  
  假如有了足够的空间,保持整洁就不是那么必要了。空间越多,就越不必要保持整洁。Arlo Guthrie 闻名的民谣 Alice's Restaurant Massacre 说明了这一点:
  
  他们住在教堂楼下的大厅,里面的椅子全都搬走了,剩下一个空荡荡的大房间,所以他们想,很长时间都不用把垃圾扔出去,有的是地方装垃圾……
  
  无论如何,垃圾收集可以帮我们减轻内务整理方面的工作。
  
  显式地释放资源
  
  Java 程序中使用的绝大多数资源都是对象,垃圾收集在清理对象方面做得很好。因此,您可以使用任意多的 String。垃圾收集器最终无需您的干预就会算出它们何时失效,并收回它们使用的内存。
  
  另一方面,像文件句柄和套接字句柄这类非内存资源必须由程序显式地释放,比如使用 close()、destroy()、shutdown() 或 release() 这样的方法来释放。有些类,比如平台类库中的文件句柄流实现,提供终结器(finalizer)作为安全保证,以便当垃圾收集器确定程序不再使用资源而程序却忘了释放资源时,终结器还可以来做这个释放工作。但是尽管文件句柄提供了终结器来在您忘记了时为您释放资源,最好还是在使用完之后显式地释放资源。这样做可以更早地释放资源,降低了资源耗尽的可能。
  
  对于有些资源来说,一直等到终结(finalization)释放它们是不可取的。对于重要的资源,比如锁获取和信号量许可证,Lock 或 Semaphore 直到很晚都可能不会被垃圾收集掉。对于数据库连接这样的资源,假如您等待终结,那么肯定会消耗完资源。许多数据库服务器根据许可的容量,只接受一定数量的连接。假如服务器应用程序为每个请求都打开一个新的数据库连接,然后用完之后就不管了,那么数据库远远未到终结器关闭不再需要的连接,就会到达它的最高容量。
  
  只限于一个方法的资源
  
  多数资源都不会持续整个应用程序的生命周期,相反,它们只被用于一个活动的生命周期。当应用程序打开一个文件句柄读取文件以处理文档时,它通常读取文件后就不再需要文件句柄了。
  
  在最简单的情况下,资源在同一个方法调用中被获取、使用和释放,比如清单 1 中的 loadPropertiesBadly() 方法:
  
  清单 1. 不正确地在一个方法中获取、使用和释放资源 —— 不要这样做
  
  public static Properties loadPropertiesBadly(String fileName)
  throws IOException {
   FileInputStream stream = new FileInputStream(fileName);
   Properties props = new Properties();
   props.load(stream);
   stream.close();
   return props;
  }
  不幸的是,这个例子存在潜在的资源泄漏。假如一切进展顺利,流将会在方法返回之前被关闭。但是假如 props.load() 方法抛出一个 IOException,那么流则不会被关闭(直到垃圾收集器运行其终结器)。解决方案是使用 try...finally 机制来确保流被关闭,而不管是否发生错误,如清单 2 所示:
  
  清单 2. 正确地在一个方法中获取、使用和释放资源
  
  public static Properties loadProperties(String fileName)
  throws IOException {
   FileInputStream stream = new FileInputStream(fileName);
   try {
  Properties props = new Properties();
  props.load(stream);
  return props;
   }
   finally {
  stream.close();
   }
  }
  注重,资源获取(打开文件)是在 try 块外面进行的;假如把它放在 try 块中,那么即使资源获取抛出异常,finally 块也会运行。不仅该方法会不适当(您无法释放您没有获取的资源),finally 块中的代码也可能抛出其自己的异常,比如 NullPointerException。从 finally 块抛出的异常取代导致块退出的异常,这意味着原来的异常丢失了,不能用于帮助进行调试。 并不总像看起来那么轻易
  
  使用 finally 来释放在方法中获取的资源是可靠的,但是当涉及多个资源时,很轻易变得难以处理。下面考虑这样一个方法,它使用一个 JDBC Connection 来执行查询和迭代 ResultSet。该方法获得一个 Connection,使用它来创建一个 Statement,并执行 Statement 以得到一个 ResultSet。但是中间 JDBC 对象 Statement 和 ResultSet 具有它们自己的 close() 方法,并且当您使用完之后,应该释放这些中间对象。然而,进行资源释放的 “明显的” 方式并不起作用,如清单 3 所示:
  
  清单 3. 不成功的释放多个资源的企图 —— 不要这样做
  
  
展开更多 50%)
分享

猜你喜欢

Java 理论与实践: 良好的内务处理实践

编程语言 网络编程
Java 理论与实践: 良好的内务处理实践

Java 理论与实践:哈希

编程语言 网络编程
Java 理论与实践:哈希

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Java 理论与实践: 关于异常的争论

编程语言 网络编程
Java 理论与实践: 关于异常的争论

Java 理论与实践: 伪typedef反模式

编程语言 网络编程
Java 理论与实践: 伪typedef反模式

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

Java 理论与实践: 线程池与工作队列

编程语言 网络编程
Java 理论与实践: 线程池与工作队列

网站设计中的导航理论与实践

Web开发
网站设计中的导航理论与实践

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

删除Win7资源管理器里碍眼的图标

删除Win7资源管理器里碍眼的图标

使用XSL来显示XML数据

使用XSL来显示XML数据
下拉加载更多内容 ↓