找回密码
 立即注册
首页 业界区 安全 CopyOnWriteArrayList:写时复制机制与高效并发访问 ...

CopyOnWriteArrayList:写时复制机制与高效并发访问

薯羞 7 天前
前言

Vector无论是add方法还是get方法都加上了synchronized修饰,当多线程读写List必须排队执行,很显然这样效率比较是低下的,CopyOnWriteArrayList是读写分离的,好处是提高线程访问效率。
CopyOnWrite容器即写时复制的容器。通俗的理解是当往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器里的值Copy到新的容器,然后再往新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读 要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。
底层原理


  • CopyOnWriteArrayList的动态数组机制 -- 它内部有个volatile数组(array)来保持数据。在“添加/删除”数据时,都会新建一个数组,并将更新后的数据拷贝到新建的数组中,最后再将该数组赋值给volatile数组。这就是它叫做CopyOnWriteArrayList的原因!
  • 每一个CopyOnWriteArrayList都和一个监视器锁lock绑定,通过lock,实现了对CopyOnWriteArrayList的互斥添加/删除。
类的继承关系

CopyOnWriteArrayList实现了List接口,List接口定义了对列表的基本操作;同时实现了RandomAccess接口,表示可以随机访问(数组具有随机访问的特性);同时实现了Cloneable接口,表示可克隆;同时也实现了Serializable接口,表示可被序列化。
  1. public class CopyOnWriteArrayList implements List, RandomAccess, Cloneable, java.io.Serializable {}
复制代码
类的内部类


  • COWIterator类
COWIterator表示迭代器,其也有一个Object类型的数组作为CopyOnWriteArrayList数组的快照,这种快照风格的迭代器方法在创建迭代器时使用了对当时数组状态的引用。此数组在迭代器的生存期内不会更改,因此不可能发生冲突,并且迭代器保证不会抛出 ConcurrentModificationException。创建迭代器以后,迭代器就不会反映列表的添加、移除或者更改。在迭代器上进行的元素更改操作(remove、set 和 add)不受支持。这些方法将抛出 UnsupportedOperationException。
[code]static final class COWIterator implements ListIterator {    /** Snapshot of the array */    // 快照    private final Object[] snapshot;    /** Index of element to be returned by subsequent call to next.  */    // 游标    private int cursor;    // 构造函数    private COWIterator(Object[] elements, int initialCursor) {        cursor = initialCursor;        snapshot = elements;    }    // 是否还有下一项    public boolean hasNext() {        return cursor < snapshot.length;    }    // 是否有上一项    public boolean hasPrevious() {        return cursor > 0;    }    // next项    @SuppressWarnings("unchecked")    public E next() {        if (! hasNext()) // 不存在下一项,抛出异常            throw new NoSuchElementException();        // 返回下一项        return (E) snapshot[cursor++];    }    @SuppressWarnings("unchecked")    public E previous() {        if (! hasPrevious())            throw new NoSuchElementException();        return (E) snapshot[--cursor];    }        // 下一项索引    public int nextIndex() {        return cursor;    }        // 上一项索引    public int previousIndex() {        return cursor-1;    }    /**        * Not supported. Always throws UnsupportedOperationException.        * @throws UnsupportedOperationException always; {@code remove}        *         is not supported by this iterator.        */    // 不支持remove操作    public void remove() {        throw new UnsupportedOperationException();    }    /**        * Not supported. Always throws UnsupportedOperationException.        * @throws UnsupportedOperationException always; {@code set}        *         is not supported by this iterator.        */    // 不支持set操作    public void set(E e) {        throw new UnsupportedOperationException();    }    /**        * Not supported. Always throws UnsupportedOperationException.        * @throws UnsupportedOperationException always; {@code add}        *         is not supported by this iterator.        */    // 不支持add操作    public void add(E e) {        throw new UnsupportedOperationException();    }    @Override    public void forEachRemaining(Consumer

相关推荐

您需要登录后才可以回帖 登录 | 立即注册