`
zhuhui_zj
  • 浏览: 36189 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

并发容器分析(一)--CopyOnWriteArrayList

阅读更多

一、简介

    JDK5中添加了新的concurrent包,其中包含了很多并发容器,这些容器针对多线程环境进行了优化,大大提高了容器类在并发环境下的执行效率。

    CopyOnWriteArrayList类是一个线程安全的List接口的实现,在该类的内部进行元素的写操作时,底层的数组将被完整的复制,这对于读操作远远多于写操作的应用非常适合。在CopyOnWriteArrayList上进行操作时,读操作不需要加锁,而写操作类实现中对其进行了加锁。

二、具体实现

    CopyOnWriteArrayList底层的定义如下:

public class CopyOnWriteArrayList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    private volatile transient E[] array;

    private E[] array() { return array; }

    // 该操作是加锁的,防止array在copy的时候被替换 
    private synchronized void copyIn(E[] toCopyIn, int first, int n) {
        array  = (E[]) new Object[n];
        System.arraycopy(toCopyIn, first, array, 0, n);
    }

  ...
}

    读写操作:

public class CopyOnWriteArrayList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    public E get(int index) {
     // 由于包括rangeCheck和index两个操作,并不是直接在array上执行
   // 而是使用本地变量elementData引用array数组,防止两个操作之间
   // array被替换
     E[] elementData = array();
        rangeCheck(index, elementData.length);
        return elementData[index];
    }
    
    public synchronized E set(int index, E element) { // 是同步的
        int len = array.length;
        rangeCheck(index, len);
        E oldValue = array[index];

        // 判断该写的元素与原数据是否相同
        boolean same = (oldValue == element ||
        (element != null && element.equals(oldValue)));
        
        if (!same) {
            // [1] 创建一个新数组,将原array的值拷贝至新数组
        E[] newArray = (E[]) new Object[len];
            System.arraycopy(array, 0, newArray, 0, len);
            // [2] set的元素
        newArray[index] = element;
            // [3] 替换底层array数组
        array = newArray;
        }
        return oldValue;
    }

  ...
}

    add和remove也采用相同的技术:

public class CopyOnWriteArrayList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    public synchronized boolean add(E element) {
        // [1] new and copy
        int len = array.length;
        E[] newArray = (E[]) new Object[len+1];
        System.arraycopy(array, 0, newArray, 0, len);
        // [2] add element
        newArray[len] = element;
        // [3] change base array
        array = newArray;
        return true;
    }

    public synchronized E remove(int index) {
        int len = array.length;
        rangeCheck(index, len);
        E oldValue = array[index];
        // new一个新的数组
      E[] newArray = (E[]) new Object[len-1];
        // copy index之前的元素
      System.arraycopy(array, 0, newArray, 0, index);
        // copy余下的元素
      int numMoved = len - index - 1;
        if (numMoved > 0)
            System.arraycopy(array, index+1, newArray, index, numMoved);
        // 替换array引用    
     array = newArray;
        return oldValue;
    }

  ...
}

   特别注意:在CopyOnWriteArrayList上获得的Iterator是不能进行set和remove操作的,否则会抛出异常。

 

分享到:
评论

相关推荐

    java并发容器CopyOnWriteArrayList实现原理及源码分析

    主要为大家详细介绍了java并发容器CopyOnWriteArrayList实现原理及源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    基于CopyOnWriteArrayList并发容器(实例讲解)

    下面小编就为大家带来一篇基于CopyOnWriteArrayList并发容器(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    wuhaocn#guide-doc#并发容器之CopyOnWriteArrayList1

    1. CopyOnWriteArrayList的简介 2. COW的设计思想 3. CopyOnWriteArrayList的实现原理 4. 总结 2.读线程间

    【2018最新最详细】并发多线程教程

    16.并发容器之CopyOnWriteArrayList 17.并发容器之ThreadLocal 18.一篇文章,从源码深入详解ThreadLocal内存泄漏问题 19.并发容器之BlockingQueue 20.并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理...

    Java 常见并发容器总结

    Java 常见并发容器总结 JDK 提供的这些容器大部分在 `java.util.concurrent` 包中。 - **`ConcurrentHashMap`** : 线程安全的 `HashMap` - **`CopyOnWriteArrayList`** : 线程安全的 `List`,在读多写少的场合性能...

    Java并发包讲解

    ## 线程安全-并发容器JUC--原理以及分析 1.arrayList --copyonWriteArraylist 优缺点 2.HashSet,TreeSet -- CopyONWriteArraySet,ConcurrentSkipListSet 3.hashMap , treeMap -- ConcurrentHashMap,...

    并发容器和线程池,java并发编程3

    我们挑选出⼀些⽐较有代表性的并发容器 1 类,来感受⼀下JDK⾃带的并发集合带来的“快感”。 ConcurrentLinkedQueue是⼀个基于链接节点的⽆界线程安全队列,它采⽤先进先出的规则对节点 进⾏排序,当我们添加⼀个...

    Java并发编程原理与实战

    并发容器CopyOnWriteArrayList原理与使用.mp4 并发容器ConcurrentLinkedQueue原理与使用.mp4 Java中的阻塞队列原理与使用.mp4 实战:简单实现消息队列.mp4 并发容器ConcurrentHashMap原理与使用.mp4 线程池的原理与...

    龙果java并发编程完整视频

    第47节并发容器CopyOnWriteArrayList原理与使用00:15:52分钟 | 第48节并发容器ConcurrentLinkedQueue原理与使用00:31:03分钟 | 第49节Java中的阻塞队列原理与使用00:26:18分钟 | 第50节实战:简单实现消息队列00:...

    java并发编程

    第47节并发容器CopyOnWriteArrayList原理与使用00:15:52分钟 | 第48节并发容器ConcurrentLinkedQueue原理与使用00:31:03分钟 | 第49节Java中的阻塞队列原理与使用00:26:18分钟 | 第50节实战:简单实现消息队列00:...

    Java并发编程实战

    5.2 并发容器 5.2.1 ConcurrentHashMap 5.2.2 额外的原子Map操作 5.2.3 CopyOnWriteArrayList 5.3 阻塞队列和生产者-消费者模式 5.3.1 示例:桌面搜索 5.3.2 串行线程封闭 5.3.3 双端队列与工作密取 5.4 ...

    Java 并发编程原理与实战视频

    第47节并发容器CopyOnWriteArrayList原理与使用00:15:52分钟 | 第48节并发容器ConcurrentLinkedQueue原理与使用00:31:03分钟 | 第49节Java中的阻塞队列原理与使用00:26:18分钟 | 第50节实战:简单实现消息队列00:...

    龙果 java并发编程原理实战

    第47节并发容器CopyOnWriteArrayList原理与使用00:15:52分钟 | 第48节并发容器ConcurrentLinkedQueue原理与使用00:31:03分钟 | 第49节Java中的阻塞队列原理与使用00:26:18分钟 | 第50节实战:简单实现消息队列00:...

    Java 并发编程实战

    5.2 并发容器 5.2.1 ConcurrentHashMap 5.2.2 额外的原子Map操作 5.2.3 CopyOnWriteArrayList 5.3 阻塞队列和生产者-消费者模式 5.3.1 示例:桌面搜索 5.3.2 串行线程封闭 5.3.3 双端队列与工作密取 5.4 ...

    Java并发编程(学习笔记).xmind

    并发容器 ConcurrentHashMap 用于替代同步且基于散列的Map CopyOnWriteArrayList 用于在遍历操作为主要操作的情况下替代同步的List Queue ConcurrentLinkedQueue *BlockingQueue...

    Java并发编程:阻塞队列

    我们讨论了同步容器(Hashtable、Vector),也讨论了并发容器(ConcurrentHashMap、CopyOnWriteArrayList),这些工具都为我们编写多线程程序提供了很大的方便。我们来讨论另外一类容器:阻塞队列。  在前面我们...

    Java容器.xmind

    写入时先copy一个容器副本,再添加新元素,最后替换引用 copy的容器副本过大时,速度慢,不易使用 CopyOnWriteArraySet 底层使用CopyOnWriteArrayList实现 使用addIfAbsent()添加元素时,会遍历数组,如果存在元素,则...

Global site tag (gtag.js) - Google Analytics