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

Java并发之CopyOnWriteArrayList

时间:2015-01-15 19:47:19      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:

CopyOnWriteArrayList是线程安全的、并且读操作无锁的ArrayList。
不像ArrayList默认初始化大小为10的Object[],CopyOnWriteArrayList默认初始化大小为0的Object[]
1,add(E)
add方法没有给整个方法加synchronized关键字,而是使用ReentrantLock来保证线程安全。
该方法和ArrayList的add方法不同,ArrayList在add时候如果List中元素个数超出Object[]大小,则扩容,默认扩容1.5倍,而CopyOnWriteArrayList是新创建一个比原来大1的数组,然后将新元素放在最后。

2,remove(E)
在ArrayList的remove方法中,代码如下:

public E remove(int index) {
...
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
   System.arraycopy(elementData, index+1, elementData, index,
    numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}


从代码可以看出,ArrayList是直接操作原数组,利用 System.arraycopy将index之后的元素往前挪。
而在CopyOnWriteArrayList的remove中,和add方法一样,也是通过ReentrantLock保证线程安全,代码如下:

public E remove(int index) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
   Object[] elements = getArray();
   int len = elements.length;
   Object oldValue = elements[index];
   int numMoved = len - index - 1;
   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 (E)oldValue;
} finally {
   lock.unlock();
}
    }

 

 


从代码可以看出,CopyOnWriteArrayList新创建了一个大小比原来小1的新数组,然后利用System.arraycopy将原数组index前后分两次拷贝至新数组。

Java并发之CopyOnWriteArrayList

标签:

原文地址:http://www.cnblogs.com/shine_cn/p/4226922.html

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