现在的位置: 首页 > 综合 > 正文

结合安全发布与有效的不可变性来提升性能

2013年10月12日 ⁄ 综合 ⁄ 共 756字 ⁄ 字号 评论关闭

使用多个 Java 线程之间共享数据的缺点在于数据访问必须同步,从而避免出现不一致的内容视图,后者可能会导致应用程序失败。例如,Hashtable 类的 put()get() 方法是同步的。因为需要实现同步,所以 put()get() 方法在执行时将同时单独地访问数据;否则,应用程序数据结构可能会被破坏。

当某个应用程序的线程频繁访问这些方法,导致线程出现阻塞时,这些方法的同步点将成为瓶颈。每次只能有一个线程获得内容的访问权。而其他线程必须等待。如果线程出现排队等候(如果不是这样,线程能够进行其他有用操作),性能和吞吐量将下降。当性能分析显示同步方法实际上会导致排队点时,对代码进行优化是有益的。

对于很少进行修改的数据,一种被称为分代数据结构(generational data structure)的技术允许您使用较低的 volatile 开销来安全地发布可变数据结构。当数据结构被频繁访问但很少进行修改时,这将获得性能增益。例如,可以使用未同步的数据结构如 HashMap,而不是同步的数据结构如 Hashtable。该技术的关键内容包括:

  1. 发生更新时,制作数据结构的新副本。
  2. 完全填充它。
  3. 使用 volatile 引用将更新安全地发布到所有客户。

使用该技术,getput 操作永远不会在数据结构的同一个示例上同时执行。将确保两个线程不会尝试同时更新数据结构,并且读取线程会始终查看一致的、最新版本的数据。(即使数据被频繁更新,仍可以使用该方法,不过通过改善并发性而获得的性能增益将损失。频繁地重新填充数据结构可能会抵消由消除同步存取器方法而获得的性能增益。)

本文转自:IBM developerWorks 中国

 

抱歉!评论已关闭.