- 1
- 0
- 约1.47万字
- 约 10页
- 2017-08-20 发布于浙江
- 举报
ConcurrentHashMap 的和 CopyOnWriteArrayList 提供线程安全性和已改进的可伸缩性
eJava 理论与实践: 并发集合类
ConcurrentHashMap 和 CopyOnWriteArrayList 提供线程安全性和已改进的可伸缩性
级别: 初级
Brian Goetz (brian@), 首席顾问, Quiotix Corp
2003 年 9 月 28 日
DougLea的 util.concurrent 包除了包含许多其他有用的并发构造块之外,还包含了一些主要集合类型 List 和 Map 的高性能的、线程安全的实现。在本月的 Java理论与实践中,BrianGoetz向您展示了用 ConcurrentHashMap 替换 Hashtable 或 synchronizedMap ,将有多少并发程序获益。您可以在本文的 论坛中与作者以及其他读者共享您的想法(您也可以点击文章顶部或者底部的 讨论进入论坛)。
在Java类库中出现的第一个关联的集合类是 Hashtable ,它是JDK 1.0的一部分。 Hashtable 提供了一种易于使用的、线程安全的、关联的map功能,这当然也是方便的。然而,线程安全性是凭代价换来的―― Hashtable 的所有方法都是同步的。此时,无竞争的同步会导致可观的性能代价。 Hashtable 的后继者 HashMap 是作为JDK1.2中的集合框架的一部分出现的,它通过提供一个不同步的基类和一个同步的包装器 Collections.synchronizedMap ,解决了线程安全性问题。通过将基本的功能从线程安全性中分离开来, Collections.synchronizedMap 允许需要同步的用户可以拥有同步,而不需要同步的用户则不必为同步付出代价。
Hashtable 和 synchronizedMap 所采取的获得同步的简单方法(同步 Hashtable 中或者同步的 Map 包装器对象中的每个方法)有两个主要的不足。首先,这种方法对于可伸缩性是一种障碍,因为一次只能有一个线程可以访问hash表。同时,这样仍不足以提供真正的线程安全性,许多公用的混合操作仍然需要额外的同步。虽然诸如 get() 和 put() 之类的简单操作可以在不需要额外同步的情况下安全地完成,但还是有一些公用的操作序列,例如迭代或者put-if-absent(空则放入),需要外部的同步,以避免数据争用。
有条件的线程安全性
同步的集合包装器 synchronizedMap 和 synchronizedList ,有时也被称作 有条件地线程安全――所有单个的操作都是线程安全的,但是多个操作组成的操作序列却可能导致数据争用,因为在操作序列中控制流取决于前面操作的结果。 清单1中第一片段展示了公用的put-if-absent语句块――如果一个条目不在 Map 中,那么添加这个条目。不幸的是,在 containsKey() 方法返回到 put() 方法被调用这段时间内,可能会有另一个线程也插入一个带有相同键的值。如果您想确保只有一次插入,您需要用一个对 Map m 进行同步的同步块将这一对语句包装起来。
清单1中其他的例子与迭代有关。在第一个例子中, List.size() 的结果在循环的执行期间可能会变得无效,因为另一个线程可以从这个列表中删除条目。如果时机不得当,在刚好进入循环的最后一次迭代之后有一个条目被另一个线程删除了,则 List.get() 将返回 null ,而 doSomething() 则很可能会抛出一个 NullPointerException 异常。那么,采取什么措施才能避免这种情况呢?如果当您正在迭代一个 List 时另一个线程也可能正在访问这个 List ,那么在进行迭代时您必须使用一个 synchronized 块将这个 List 包装起来,在 List 1 上同步,从而锁住整个 List 。这样做虽然解决了数据争用问题,但是在并发性方面付出了更多的代价,因为在迭代期间锁住整个 List 会阻塞其他线程,使它们在很长一段时间内不能访问这个列表。
集合框架引入了迭代器,用于遍历一个列表或者其他集合,从而优化了对一个集合中的元素进行迭代的过程。然而,在 java.util 集合类中实现的迭代器极易崩溃,也就是说,如果在一个线程正在通过一个 Iterator 遍历集合时,另一个线程也来修改这个集合,那么接下来的 Iterator.hasNext() 或 Iterator.next() 调用将抛出 ConcurrentModificationException 异常。就拿刚才这个例子来讲,如果想要防止出现 ConcurrentModificationException 异常,那么当您正在进行迭代时,您必须使用一个在 List l 上同步的 synchronized
您可能关注的文档
- cache结构与操作的.ppt
- CAD2010机械专用安椎陌教程.doc
- cad 表格和excel表傅鸟相互转换的方法.doc
- Cad2014快速统计对系捏数量的2种方法.doc
- Cadence Allegro导车啮dxf格式CAD文件.doc
- Cadence Design ent的ry HDL 教程.doc
- Caddx NetworX系列钡抹警主机&设备简介.ppt
- CAD2008基础入门的.ppt
- cad制图初学者基础降奶程.doc
- CAD形位公差标注方返抹.ppt
- 2026届湖南省湘南中学高二物理第一学期期末达标检测模拟试题含解析.doc
- 福建厦门事业单位联考笔试考试练习题 .docx
- 福建厦门事业单位联考综合应用能力考试练习题 .docx
- 福建厦门人社局事业单位综合应用能力考试练习题 .docx
- 2026届青海省平安区第一高级中学物理高三上期末达标测试试题含解析.doc
- 福建厦门住房与城乡建设局事业单位编制综合应用能力练习题 .docx
- 福建厦门图书馆事业单位编制笔试综合应用能力练习题 .docx
- 湖北省恩施州清江外国语学校2026届物理高二第一学期期末学业质量监测模拟试题含解析.doc
- 2026届北京市育英中学高三物理第一学期期中调研试题含解析.doc
- 2026届吉林省舒兰市一中物理高二第一学期期中检测模拟试题含解析.doc
原创力文档

文档评论(0)