您的位置:首页 > 运维架构

使用 CopyOnWriteArrayList 和 CopyOnWriteArraySet

2011-08-16 11:36 393 查看
 

在 Doug Lea 的 Concurrent Programming in Java一书的第 2 章第 2.4.4 节(请参阅
参考资料)中,对 copy-on-write 模式作了最好的描述。实质上,这个模式声明了,为了维护对象的一致性快照,要依靠不可变性(immutability)来消除在协调读取不同的但是相关的属性时需要的同步。对于集合,这意味着如果有大量的读(即
get()
) 和迭代,不必同步操作以照顾偶尔的写(即
add()
)调用。对于新的
CopyOnWriteArrayList
CopyOnWriteArraySet
类,所有可变的(mutable)操作都首先取得后台数组的副本,对副本进行更改,然后替换副本。这种做法保证了在遍历自身更改的集合时,永远不会抛出
ConcurrentModificationException
。遍历集合会用原来的集合完成,而在以后的操作中使用更新后的集合。

 在读和写都存在,而写的情况较少,大多数时候都是读的情况下,可以对当前
集合copy副本,写副本,读取当前集合,后续操作中副本替换当前集合。保证读和写不冲突。

这些新的集合,
CopyOnWriteArrayList
CopyOnWriteArraySet
,最适合于读操作通常大大超过写操作的情况。一个最常提到的例子是使用监听器列表。已经说过,Swing 组件还没有改为使用新的集合。相反,它们继续使用
javax.swing.event.EventListenerList
来维护它们的监听器列表。

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

/**

  * 注册一个事件监听者

  * @param listener

  */

 private void registerEventListener(String eventType, EventListener listener) {

  Set<EventListener> set = listeners.get(eventType);

  if (set == null) {

   set = new CopyOnWriteArraySet<EventListener>();

   listeners.put(eventType, set);

  }

  set.add(listener);

  if(!EventContext.dispatchers.contains(this)) {

   EventContext.dispatchers.add(this);

  }

 }

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  iterator swing string java null