读书人

jdk 五并发包中CopyOnWrite类的用法

发布时间: 2012-09-13 09:51:53 作者: rapoo

jdk 5并发包中CopyOnWrite类的用法

jdk 5的concurrent包中,添加了几个CopyOnWrite开头的类,包括CopyOnWriteHashMap,CopyOnWriteArrayList,CopyOnWriteArraySet。 copy-on-write模式声明了,为了维护对象的一致性快照,要依靠不可变性(immutability)来消除在协调读取不同的但是相关的属性时需要的同步。对于集合,这意味着如果有大量的读(即?get()?) 和迭代,不必同步操作以照顾偶尔的写(即?add()?)调用。对于新的?CopyOnWriteArrayList?和?CopyOnWriteArraySet?类,所有可变的(mutable)操作都首先取得后台数组的副本,对副本进行更改,然后替换副本。这种做法保证了在遍历自身更改的集合时,永远不会抛出?ConcurrentModificationException?。遍历集合会用原来的集合完成,而在以后的操作中使用更新后的集合。这些新的集合,?CopyOnWriteArrayList?和?CopyOnWriteArraySet?,最适合于读操作通常大大超过写操作的情况。

如下所示,集合的使用与它们的非 copy-on-write 替代物完全一样。只是创建集合并在其中加入或者删除元素。即使对象加入到了集合中,原来的?Iterator?也可以进行,继续遍历原来集合中的项。

?

import java.util.*;import java.util.concurrent.*;public class CopyOnWrite {  public static void main(String args[]) {    List list1 = new CopyOnWriteArrayList(Arrays.asList(args));    List list2 = new ArrayList(Arrays.asList(args));    Iterator itor1 = list1.iterator();    Iterator itor2 = list2.iterator();    list1.add("New");    list2.add("New");    try {      printAll(itor1);    } catch (ConcurrentModificationException e) {      System.err.println("Shouldn't get here");    }    try {      printAll(itor2);    } catch (ConcurrentModificationException e) {      System.err.println("Will get here.");    }  }  private static void printAll(Iterator itor) {    while (itor.hasNext()) {      System.out.println(itor.next());    }  }}

?这个示例程序用命令行参数创建?CopyOnWriteArrayList?和?ArrayList?这两个实例。在得到每一个实例的?Iterator?后,分别在其中加入一个元素。当?ArrayList?迭代因一个?ConcurrentModificationException?问题而立即停止时,?CopyOnWriteArrayList?迭代可以继续,不会抛出异常,因为原来的集合是在得到 iterator 之后改变的。如果这种行为(比如通知原来一组事件监听器中的所有元素)是您需要的,那么最好使用 copy-on-write 集合。如果不使用的话,就还用原来的,并保证在出现异常时对它进行处理。

?

[1].驯服 Tiger: 并发集合?http://www.ibm.com/developerworks/cn/java/j-tiger06164/

读书人网 >编程

热点推荐