码迷,mamicode.com
首页 > 编程语言 > 详细

java并发容器CopyOnWriteArrayList 使用场景和内部实现分析

时间:2015-07-07 16:24:56      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:

java并发容器CopyOnWriteArrayList
CopyOnWriteArrayList
顾名思义,当数组有变化时重新建立一个新的数组

其设计是对于线程安全容器Vector使用中出现问题的一种解.
在Vector容器中,当需要执行复合操作
例如:
//代码1

class Observable 
{
private List<Observer> observers=new Vector<Observer>();

public void addObserver(){...}
public void removeObserver(){...}
public void notify()
{
Iterator<Observer> itr=observers.iterator();
while(itr.hasNext()){
Observer observer=itr.next();
observer.notify();
}
return;
}
}

 

Observable中的notify方法在单线程中的实现是正常的,但在多线程中,由于在notify执行过程中observers数组的内容可能会发生改变,导致遍历失效.即使observers本身是线程安全的也于是无补

通常解决这个问题,可以使用同步方法或者加锁
//代码2

class Observable 
{
private List<Observer> observers=new Vector<Observer>();

public synchronized void addObserver(){...}

public synchronized void removeObserver(){...}

//同步方法
public synchronized void notify()
{
Iterator<Observer> itr=observers.iterator();
while(itr.hasNext()){
Observer observer=itr.next();
observer.notify();
}
return;
}
}

  

这样的解决方案中notify的同步导致另外一个问题,即活跃性问题.当observers中有很多元素或者每一个元素的notify方法调用需要很久时,此方法将长时间持有锁.导致其他任何想修改observers的行为阻塞.最后严重影响程序性能

CopyOnWriteArrayList即在这种场景下使用.一个需要在多线程中操作,并且频繁遍历.
其解决了由于长时间锁定整个数组导致的性能问题.
其解决方案即写时拷贝。

我们先来贴出使用CopyOnWriteArrayList的Observable代码
//代码3

class Observable 
{
private List<Observer> observers=new CopyOnWriteArrayList<Observer>();

public void addObserver(){...}

public void removeObserver(){...}

public void notify()
{
Iterator<Observer> itr=observers.iterator();
while(itr.hasNext()){
Observer observer=itr.next();
observer.notify();
}
return;
}
}

 

Observable的notify方法和代码1相同.但其不会有多线程同时操作的问题.其中的奥秘,通过分析源码可知
当CopyOnWriteArrayList添加或者删除元素时,其实现为根据当前数组重新建立一个新数组..

Iterator<Observer> itr=observers.iterator();

 


当我们获取CopyOnWriteArrayList的迭代器时,迭代器内保存当前数组的引用.之后如果别的线程改变CopyOnWriteArrayList中元素,则根据CopyOnWriteArrayList的特性,其实并没有改变这个迭代器指向数组的内容.

如图

技术分享

java并发容器CopyOnWriteArrayList 使用场景和内部实现分析

标签:

原文地址:http://www.cnblogs.com/duchanggang/p/4627082.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!