首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Java 容器源码分析之 Map(5)

Java 容器源码分析之 Map(5)

选择适当的 Map
应使用哪种 Map? 它是否需要同步? 要获得应用程序的最佳性能,这可能是所面临的两个最重要的问题。当使用通用 Map 时,调整 Map 大小和选择负载因子涵盖了 Map 调整选项。
以下是一个用于获得最佳 Map 性能的简单方法
  • 将您的所有 Map 变量声明为 Map,而不是任何具体实现,即不要声明为 HashMap 或 Hashtable,或任何其他 Map 类实现。 Map criticalMap = new HashMap(); //好HashMap criticalMap = new HashMap(); //差这使您能够只更改一行代码即可非常轻松地替换任何特定的 Map 实例。
  • 下载 Doug Lea 的 util.concurrent 程序包 ( )。将 ConcurrentHashMap 用作默认 Map。当移植到 1.5 版时,将 java.util.concurrent.ConcurrentHashMap 用作您的默认 Map。不要将 ConcurrentHashMap 包装在同步的包装器中,即使它将用于多个线程。使用默认大小和负载因子。
  • 监测您的应用程序。如果发现某个 Map 造成瓶颈,则分析造成瓶颈的原因,并部分或全部更改该 Map 的以下内容:Map 类;Map 大小;负载因子;关键对象 equals() 方法实现。专用的 Map 的基本上都需要特殊用途的定制 Map 实现,否则通用 Map 将实现您所需的性能目标。

Map 选择
也许您曾期望更复杂的考量,而这实际上是否显得太容易? 好的,让我们慢慢来。首先,您应使用哪种 Map?答案很简单: 不要为您的设计选择任何特定的 Map,除非实际的设计需要指定一个特殊类型的 Map。设计时通常不需要选择具体的 Map 实现。您可能知道自己需要一个 Map,但不知道使用哪种。而这恰恰就是使用 Map 接口的意义所在。直到需要时再选择 Map 实现 — 如果随处使用“Map”声明的变量,则更改应用程序中任何特殊 Map 的 Map 实现只需要更改一行,这是一种开销很少的调整选择。是否要使用默认的 Map 实现? 我很快将谈到这个问题。
同步 Map
同步与否有何差别? (对于同步,您既可以使用同步的 Map,也可以使用 Collections.synchronizedMap() 将未同步的 Map 转换为同步的 Map。后者使用“同步的包装器”)这是一个异常复杂的选择,完全取决于您如何根据多线程并发访问和更新使用 Map,同时还需要进行维护方面的考虑。例如,如果您开始时未并发更新特定 Map,但它后来更改为并发更新,情况将如何? 在这种情况下,很容易在开始时使用一个未同步的 Map,并在后来向应用程序中添加并发更新线程时忘记将此未同步的 Map 更改为同步的 Map。这将使您的应用程序容易崩溃(一种要确定和跟踪的最糟糕的错误)。但如果默认为同步,则将因随之而来的可怕性能而序列化执行多线程应用程序。看起来,我们需要某种决策树来帮助我们正确选择。
Doug Lea 是纽约州立大学奥斯威戈分校计算机科学系的教授。他创建了一组公共领域的程序包(统称 util.concurrent),该程序包包含许多可以简化高性能并行编程的实用程序类。这些类中包含两个 Map,即 ConcurrentReaderHashMap 和 ConcurrentHashMap。这些 Map 实现是线程安全的,并且不需要对并发访问或更新进行同步,同时还适用于大多数需要 Map 的情况。它们还远比同步的 Map(如 Hashtable)或使用同步的包装器更具伸缩性,并且与 HashMap 相比,它们对性能的破坏很小。util.concurrent 程序包构成了 JSR166 的基础;JSR166 已经开发了一个包含在 Java 1.5 版中的并发实用程序,而 Java 1.5 版将把这些 Map 包含在一个新的 java.util.concurrent 程序包中。


所有这一切意味着您不需要一个决策树来决定是使用同步的 Map 还是使用非同步的 Map, 而只需使用 ConcurrentHashMap。当然,在某些情况下,使用 ConcurrentHashMap 并不合适。但这些情况很少见,并且应具体情况具体处理。这就是监测的用途。
结束语
    可以非常轻松地创建一个用于比较各种 Map 性能的测试类。更重要的是,集成良好的监测器可以在开发过程中快速、轻松地识别性能瓶颈 - 集成到 IDE 中的监测器通常被较频繁地使用,以便帮助构建一个成功的工程。现在,您已经拥有了一个监测器并了解了有关通用 Map 及其性能的基础知识,可以开始运行您自己的测试,以查明您的应用程序是否因 Map 而存在瓶颈以及在何处需要更改所使用的 Map。
返回列表