javaSE 并发包CopyOnWriteArrayList源码分析

CopyOnWriteArrayList

每个CopyOnwriteArrayList对象都存在一个volatile修饰的array数组对象来存放具体元素,使用独占锁ReentrantLock对CopyOnWriteArrayList的新增修改进行原子性操作保证,源码:

    final transient ReentrantLock lock = new ReentrantLock();

private transient volatile Object[] array;

新增源码如下:

 public boolean add(E e) {

        final ReentrantLock lock = this.lock;//获取独占锁

        lock.lock();//加锁,保证操作原子性

        try {

            Object[] elements = getArray();//获取array对象数组

            int len = elements.length;

//复制array数组到新数组,添加元素到新数组

            Object[] newElements = Arrays.copyOf(elements, len + 1);

            newElements[len] = e;

setArray(newElements);//使用新数组替换添加前的数组

            return true;

        } finally {

            lock.unlock();//释放锁

          }

}

修改及删除原理一样。

弱一致问题

public E get(int index) {

        return get(getArray(), index);

}

   

final Object[] getArray() {

        return array;

}    

private E get(Object[] a, int index) {

        return (E) a[index];

从上面的代码可以看出,在调用get(int index)方法时,要执行下面两个方法,三个操作并没有加锁进行同步,这三个方法操作的是该对象的array数组,假设在执行三个方法的途中进行新增、删除、修改操作后是使用新的数组替换原来的数组,但是这三个方法操作的还是原来的array数组,这就是写时复制策略产生的弱一致性问题。

弱一致性的迭代器

迭代器:

 public Iterator<E> iterator() {

        return new COWIterator<E>(getArray(), 0);

}

迭代器构建时也是直接使用getArray()获取数组,相当于构建了一份快照,原理如上,也会产生迭代遍历弱一致的效果。

 

CopyOnwriterArraySet

public class CopyOnWriteArraySet<E> extends AbstractSet<E>

        implements java.io.Serializable {}

可以知道:

 

CopyOnWriteArraySet继承于AbstractSet,这就意味着它是一个集合

 

实际上,CopyOnWriteArraySet包含CopyOnWriteArrayList对象,它是通过CopyOnWriteArrayList实现的,而CopyOnWriteArrayList本质是个动态数组队列,所以CopyOnWriteArraySet相当于通过通过动态数组实现的“集合”!

 

CopyOnWriteArrayList中允许有重复的元素;但是,CopyOnWriteArraySet它不能有重复集合

 

因此,CopyOnWriteArrayList额外提供了addIfAbsent()和addAllAbsent()这两个添加元素的API,通过这些API来添加元素时,只有当元素不存在时才执行添加操作!

 

至于CopyOnWriteArraySet的“线程安全”机制,和CopyOnWriteArrayList一样,是通过volatile和互斥锁来实现的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值