zoukankan      html  css  js  c++  java
  • CopyOnWriteArrayList

      JDK 的 CopyOnWriteArrayList/CopyOnWriteArraySet 容器正是采用了 COW 思想,它是如何工作的呢?简单来说,就是平时查询的时候,都不需要加锁,随便访问,只有在更新的时候,才会从原来的数据复制一个副本出来,然后修改这个副本,最后把原数据替换成当前的副本。修改操作的同时,读操作不会被阻塞,而是继续读取旧的数据。这点要跟读写锁区分一下。
    1.1 数据结构

    在修改时,复制出一个新数组,修改的操作在新数组中完成,最后将新数组交由array变量指向。

    其中:array为数据容器,使用volatile关键字,保证数据的可见性;

    使用ReentrantLock,作为锁,在set(),add(),remove()方法中均适用

    /** The lock protecting all mutators */
    final transient ReentrantLock lock = new ReentrantLock();

    /** The array, accessed only via getArray/setArray. */
    private transient volatile Object[] array;
    1.2 使用锁----以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();
      }
    }

    在get方法中没有使用到Lock锁;

    在生成遍历器类中,没有使用到锁,其操作的都是原数组。

    1.3 缺点
    1: 内存占用,每一次的add、set和remove方法,都需要将List的数组数据拷贝出,复制一个数组出来;
    2:数据一致性,没有保证数据的实时一致性,只是保证了最终一致性。例如两个线程,一个进行数据修改,一个进行遍历操作。如果遍历的过程中出现数据修改,但是遍历的还是之前的数据。

    1.优点

    对于一些读多写少的数据,写入时复制的做法就很不错,例如配置、黑名单、物流地址等变化非常少的数据,这是一种无锁的实现。可以帮我们实现程序更高的并发。

    CopyOnWriteArrayList 并发安全且性能比 Vector 好。Vector 是增删改查方法都加了synchronized 来保证同步,但是每个方法执行的时候都要去获得锁,性能就会大大下降,而 CopyOnWriteArrayList 只是在增删改上加锁,但是读不加锁,在读方面的性能就好于 Vector。

    2.缺点

    数据一致性问题。这种实现只是保证数据的最终一致性,在添加到拷贝数据而还没进行替换的时候,读到的仍然是旧数据。

    内存占用问题。如果对象比较大,频繁地进行替换会消耗内存,从而引发 Java 的 GC 问题,这个时候,我们应该考虑其他的容器,例如 ConcurrentHashMap。

     

     

  • 相关阅读:
    Sql与Asp.Net数据类型对应
    EditPlus 使用技巧集萃
    VB.NET and C# Comparison
    测试后行之CodeSmith模板
    ASP.NET需要改进的地方
    LeetCode: Minimum Path Sum
    LeetCode: Merge k Sorted Lists
    LeetCode: Merge Intervals
    LeetCode: Maximum Subarray
    LeetCode: Median of Two Sorted Arrays
  • 原文地址:https://www.cnblogs.com/mayang2465/p/14674911.html
Copyright © 2011-2022 走看看