当前位置:首页 > 开发 > 编程语言 > 编程 > 正文

CopyOnWriteArrayList vs ArrayList

发表于: 2013-11-18   作者:bylijinnan   来源:转载   浏览:
摘要: package com.ljn.base; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** * 总述: * 1.ArrayListi不是线程安全的,CopyO
package com.ljn.base;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 总述:
 * 1.ArrayListi不是线程安全的,CopyOnWriteArrayList是线程安全的。
 * 2.ArrayListi读的时候不能写:在遍历时不能执行list.remove,list.add;但可以执行iterator.remove。
 * CopyOnWriteArrayList则相反:可执行list.remove,list.add,但不能执行iterator.remove。
 * 3.CopyOnWriteArrayList用在“读比写频繁得多”的情形下。例如多个线程要遍历,而只有少数线程要写。
 * 这样就会有一个问题:读的时候可以写吗?可以,因为:
 * 4.CopyOnWriteArrayList在执行写操作时,会把当前数组元素复制一份,例如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();
            }
    }
       
    5.CopyOnWriteArrayList当前线程开始遍历(创建Iterator)时,只会看到当前数组的元素,在遍历过程中,
    如果原数组发生了变化(其他线程执行add或remove),当前线程是看不到的。以下是创建Iterator的源码:
    
        private final Object[] snapshot;
        private int cursor;

        private COWIterator(Object[] elements, int initialCursor) {
            cursor = initialCursor;
            snapshot = elements;
        }
        
 */
public class CopyOnWriteArrayListTest {

    public final static void main(String args[]) {
        
        testCopyOnWriteArrayList();
        
        testArrayList();
        
    }

    private static void testCopyOnWriteArrayList() {
        List<String> list = new CopyOnWriteArrayList<String>();
        list.add("a");
        list.add("b");
        Iterator<String> iterator = list.iterator();
        int j = 0;
        
        //will output current array: "a" and "b"
        while (iterator.hasNext()) {
            String item = iterator.next();
            System.out.println(item);
            list.add("c" + (j++));  //操作成功。但不会马上反映在本次while循环中,因为:
            /*
            An array you are looking at currently (lets say your iterator) will never change. 
            When you read from an array you are reading it as it was when you started reading. 
            If the CopyOnWriteArrayList changes by another thread, the array you're currently observing will not be affected
            */
            
            if (item.equals("b")) {
                list.remove(item);  //ok
            }
            //iterator.remove(); //UnsupportedOperationException
        }
        System.out.println(list);   //[a, c0, c1]
    }

    private static void testArrayList() {
        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("b");
        list.add("z");
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String item = iterator.next();
            System.out.println(item);
            iterator.remove(); //ok
            
            //list.remove(item);  //ConcurrentModificationException
            //list.add("c");  //ConcurrentModificationException
            //iterator.add();    //does not have this method on Iterator
        }
        System.out.println(list);   //empty list: []
    }
}

CopyOnWriteArrayList vs ArrayList

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
CopyOnWriteArrayList是ArrayList 的一个线程安全的变体,其中所有可变操作(add、set等等)都是通
一、CopyOnWriteArrayList 制作数组的干净复本是一项成本极高的操作,在时间和内存这两方面均有开销
CopyOnWriteArrayList是ArrayList 的一个线程安全的变体,其中所有可变操作(add、set等等)都是通
一、 核心思想: CopyOnWriteArrayList的核心思想是利用高并发往往是读多写少的特性,对读操作不加
CopyOnWriteArrayList是ArrayList 的一个线程安全的变体,其中所有可变操作(add、set等等)都是通
CopyOnWriteArrayList是ArrayList 的一个线程安全的变体,其中所有可变操作(add、set等等)都是通
一、 核心思想: CopyOnWriteArrayList的核心思想是利用高并发往往是读多写少的特性,对读操作不加
/* Author: Jiangong SUN */ I'll add 5 million numbers using ArrayList, List<object> and
初识CopyOnWriteArrayList 第一次见到CopyOnWriteArrayList,是在研究JDBC的时候,每一个数据库的Dr
上一篇我们提到了利用Arraylist对Hashtable进行排序,下面我们就对ArrayList进行一个简单的了解。因
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号