ITPub博客

首页 > 应用开发 > Java > Java并发之CopyOnWriteArrayList

Java并发之CopyOnWriteArrayList

原创 Java 作者:541732025 时间:2014-04-01 13:35:09 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方法中,代码如下:

点击(此处)折叠或打开

  1. public E remove(int index) {
  2. ...
  3. E oldValue = (E) elementData[index];
  4. int numMoved = size - index - 1;
  5. if (numMoved > 0)
  6.    System.arraycopy(elementData, index+1, elementData, index,
  7.     numMoved);
  8. elementData[--size] = null; // Let gc do its work
  9. return oldValue;
  10. }

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

点击(此处)折叠或打开

  1. public E remove(int index) {
  2. final ReentrantLock lock = this.lock;
  3. lock.lock();
  4. try {
  5.    Object[] elements = getArray();
  6.    int len = elements.length;
  7.    Object oldValue = elements[index];
  8.    int numMoved = len - index - 1;
  9.    if (numMoved == 0)
  10.         setArray(Arrays.copyOf(elements, len - 1));
  11.    else {
  12.         Object[] newElements = new Object[len - 1];
  13.         System.arraycopy(elements, 0, newElements, 0, index);
  14.         System.arraycopy(elements, index + 1, newElements, index,numMoved);
  15.         setArray(newElements);
  16.    }
  17.    return (E)oldValue;
  18. } finally {
  19.    lock.unlock();
  20. }
  21.     }

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


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/28912557/viewspace-1133900/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: Java实现归并排序
请登录后发表评论 登录
全部评论

注册时间:2013-05-23

  • 博文量
    127
  • 访问量
    515728