CopyOnWriteArrayList

来源:互联网 发布:软件开发流程文档 编辑:程序博客网 时间:2024/05/17 09:20

1.类声明:

//写时复制容器。可以进行并发的读,不需要加锁,写的时候拷贝一份进行写,写完将原来的容器指向新的容器,写的时候要加锁。不能保证数据的实时一致性,只能保证最终一致性。public class CopyOnWriteArrayList<E>    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

2.变量:

//写的时候加的锁final transient ReentrantLock lock = new ReentrantLock();//底层使用数组实现  private transient volatile Object[] array;

3.方法:

//集合做构造参数    public CopyOnWriteArrayList(Collection<? extends E> c) {        Object[] elements;        if (c.getClass() == CopyOnWriteArrayList.class)//若集合是CopyOnWriteArrayList,则底层使用同一个数组            elements = ((CopyOnWriteArrayList<?>)c).getArray();        else {//其他集合拷贝一份数据到新数组            elements = c.toArray();            // c.toArray might (incorrectly) not return Object[] (see 6260652)            if (elements.getClass() != Object[].class)                elements = Arrays.copyOf(elements, elements.length, Object[].class);        }        setArray(elements);    }    //默认构造函数底层数组容量为0     public CopyOnWriteArrayList() {        setArray(new Object[0]);    }    //add方法,先加锁,获取底层数组,复制底层数组,然后进行写入,最后将数组指向新数组     public boolean add(E e) {        final ReentrantLock lock = this.lock;        lock.lock();        try {            Object[] elements = getArray();            int len = elements.length;            Object[] newElements = Arrays.copyOf(elements, len + 1);            newElements[len] = e;            setArray(newElements);            return true;        } finally {            lock.unlock();        }    }    //读方法不会加锁,如果此时有线程在写,会读到旧值      private E get(Object[] a, int index) {        return (E) a[index];    }