zoukankan      html  css  js  c++  java
  • Java集合(一) CopyOnWriteArrayList

    CopyOnWriteArrayList 类分析
     
    1. CopyOnWriteArrayList 其中底层实现存放数据是一个Object数组:
     
    private volatile transient Object[] array;
     
    2. CopyOnWriteArrayList 集合操作,当对集合中的元素进行修改添加或者替换删除(增删改)的时候都是用一个全局的 ReentrantLock lock锁进行控制线程安全的:
     
    transient finall ReentrantLock lock = new ReentrantLock();
     
    3. 创建其对象,默认设置一个长度为0的数组,赋值给array变量。
     
    public CopyOnWriteArrayList() {
      setArray(new Object[0]);
    }
     
    4. 每次添加元素都创建一个新的数组,将原数组的数据复制到新的数组中,将新添加的元素放在新数组的末尾,重新将新数组赋值给 array , 代码如下:
     
    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. 因为存放数据的Object[] array 为volatile 类型的,所以在取数据的时候,没有加 lock锁。
     
    6. 在此类中set方法中涉及到 happens-before 原则的代码如下:
    public E set(int index, E element) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                Object[] elements = getArray();
                E oldValue = get(elements, index);
    
                if (oldValue != element) {
                    int len = elements.length;
                    Object[] newElements = Arrays.copyOf(elements, len);
                    newElements[index] = element;
                    setArray(newElements);
                } else {
                    // Not quite a no-op; ensures volatile write semantics
                    setArray(elements);
                }
                return oldValue;
            } finally {
                lock.unlock();
            }
        }
    关键代码在else代码块,重新到主内存中取了次链表中的元素。
     
    7. 相关类CopyOnWriteArraySet内部实现是一个CopyOnWriteArrayList,代码如下:
       private final CopyOnWriteArrayList<E> al;
    
        /**
         * Creates an empty set.
         */
        public CopyOnWriteArraySet() {
            al = new CopyOnWriteArrayList<E>();
        }

    完。。。

  • 相关阅读:
    在Arch上使用Fcitx5
    博客园图片居中
    冒泡排序算法
    检查字符串是否包含另一串字符串(c++)
    辗转相除法(求最大公约数或最小公倍数)
    二叉树等总结
    应用jfinal发送微信模板消息的一个bug
    线程中wait/notify/notifyAll的用法
    应用jfinal时要注意区分Db.query和Db.find
    从源码角度简单看StringBuilder和StringBuffer的异同
  • 原文地址:https://www.cnblogs.com/qq-361807535/p/7107131.html
Copyright © 2011-2022 走看看