CopyOnWriteArrayList 源码分析

来源:互联网 发布:岛国中文字幕下载软件 编辑:程序博客网 时间:2024/05/19 06:36

1.CopyOnWriteArrayList 是线程安全的ArrayList,适用于保存的数据量不大,读操作远多于写操作,对实时性要求不高的场景。CopyOnWriteArrayList 对读操作不同步,对写操作同步。在进行写操作时,会对共享变量进行COPY,在副本上进行更新,然后将更新好的副本替换掉原来的共享变量。写操作开销比较大。由于读操作不需同步,所以在某线程进行写操作时,其他线程可以进行读操作。这样也就导致了数据不是实时一致的。

2.CopyOnWriteArrayList 属性

 
    transient final ReentrantLock lock = new ReentrantLock();//用于控制写操作的并发

    /** The array, accessed only via getArray/setArray. */
    private volatile transient Object[] array;//保存元素


3.add函数源码

  <pre name="code" class="java">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();//解锁   } }

总体来说比较简单

4 .remove函数源码

public E remove(int index) {    final ReentrantLock lock = this.lock;    // 获取“锁”    lock.lock();    try {        // 获取原始”volatile数组“中的数据和数据长度。        Object[] elements = getArray();        int len = elements.length;        // 获取elements数组中的第index个数据。        E oldValue = get(elements, index);        int numMoved = len - index - 1;        // 如果被删除的是最后一个元素,则直接通过Arrays.copyOf()进行处理,而不需要新建数组。        // 否则,新建数组,然后将”volatile数组中被删除元素之外的其它元素“拷贝到新数组中;最后,将新数组赋值给”volatile数组“。        if (numMoved == 0)            setArray(Arrays.copyOf(elements, len - 1));        else {            Object[] newElements = new Object[len - 1];            System.arraycopy(elements, 0, newElements, 0, index);            System.arraycopy(elements, index + 1, newElements, index,                             numMoved);            setArray(newElements);        }        return oldValue;    } finally {        // 释放“锁”        lock.unlock();    }}

参考:http://www.cnblogs.com/skywang12345/p/3498483.html



0 0
原创粉丝点击