码迷,mamicode.com
首页 > 其他好文 > 详细

CopyOnWriteArrayList

时间:2021-05-23 23:26:29      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:tor   一个   效率   sub   val   tran   移除   ext   turn   

CopyOnWriteArrayList

  • List 不安全

    • 并发下的List

      //java.util.ConcurrentModificationException  并发修改异常
      public class Test03 {
          public static void main(String[] args) {
              /*并发下的ArrayList 是不安全的
              * */
              ArrayList<String> list = new ArrayList<>();
              for (int i = 0; i < 10; i++) {
                  new Thread(()->{
                      list.add(UUID.randomUUID().toString().substring(0,5));
                      System.out.println(list);
                  },String.valueOf(i)).start();
              }
          }
      }
      
      //Exception in thread "2" Exception in thread "4" Exception in thread "3" Exception in thread "5" java.util.ConcurrentModificationException
      	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
      	at java.util.ArrayList$Itr.next(ArrayList.java:851)
      	at java.util.AbstractCollection.toString(AbstractCollection.java:461)
      	at java.lang.String.valueOf(String.java:2981)
      	at java.io.PrintStream.println(PrintStream.java:821)
      	at com.saxon.demo.Test03.lambda$main$0(Test03.java:22)
      
  • 查看ArrayList的add底层代码

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    
  • 查看Vector的add底层代码

    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }
    

区别:就加了个synchronized
那JDK为什么不在ArrayList的add加上synchronized呢

并且Vector的出现比ArrayList要早
为了考虑效率问题所以去掉了synchronized

解决方案

//java.util.ConcurrentModificationException  并发修改异常
public class Test03 {
    public static void main(String[] args) {
        /*并发下的ArrayList 是不安全的
        * 解决方案:
        * 1、Vector<String> list = new Vector<>();  不常用
        * 2、List<String> list = Collections.synchronizedList(new ArrayList<>());
        * 3. List<String> list = new CopyOnWriteArrayList<>();   推荐
        * */
        // ArrayList<String> list = new ArrayList<>();
        // Vector<String> list = new Vector<>();
        // List<String> list = Collections.synchronizedList(new ArrayList<>());
       /* CopyOnWrite 写入复制 COW 计算初程序设领域的一种优化策略
                 * 多个线程调用的时候,List读取的时候,固定的,写入(覆盖)
                 * 在写入的时候避覆盖,造成数据问题
                 * CopyOnWriteArrayList比Vector厉害在哪里 看源码*/
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
    }
}
  • 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();
    }
}

CopyOnWriteArrayList比Vector厉害在哪里?

  • Vector是增删改查方法都加了synchronized保证同步,但是每个方法执行的时候都要去获得锁,性能就会大大下降
  • 而CopyOnWriteArrayList 只是在增删改上加锁,但是读不加锁,在读方面的性能就好于Vector,CopyOnWriteArrayList支持读多写少的并发情况,读写分离写时复制出一个新的数组,完成插入、修改或者移除操作后将新数组赋值给array

CopyOnWriteArrayList

标签:tor   一个   效率   sub   val   tran   移除   ext   turn   

原文地址:https://www.cnblogs.com/saxonsong/p/14728054.html

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