CopyOnWriteArraySet 源码分析

CopyOnWriteArraySet  源码分析:

1:数据结构:

private final CopyOnWriteArrayList<E> al; 内部维护的是一个CopyOnWriteArrayList,所以CopyOnWriteArraySet的实现原理是通过CopyOnWriteArrayList的机制来实现的;

2:构造方法:

public CopyOnWriteArraySet() {

        al = new CopyOnWriteArrayList<E>();

}

创建一个空的CopyOnWriteArrayList集合,回到CopyOnWriteArrayList中,这个构造方法有两个作用:

   1):setArray(new Object[0]); 新建一个长度为0的Object数组,并且赋值给array变量;

   2):final transient ReentrantLock lock = new ReentrantLock();实例化一个独占锁对象;

3:方法分析,这里主要分析 add  get remove  这几个常用的方法:

 1):addd方法源码分析:

public boolean add(E e) {

        return al.addIfAbsent(e);

}

内部调用CopyOnWriteArrayList 的addIfAbsent方法;

下面对addIfAbsent这个方法进行分析:

public boolean addIfAbsent(E e) {   //e=”beppe”

        Object[] snapshot = getArray();  // snapshot= Object[0]

        return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :

            addIfAbsent(e, snapshot);

    }

接下来分析indexOf(e, snapshot, 0, snapshot.length) 这个方法:

private static int indexOf(Object o, Object[] elements,

                               int index, int fence) { //o=”beppe” elements=Object[]

index=0  fence=0

        if (o == null) {   //插入空值的场景

            for (int i = index; i < fence; i++)

                if (elements[i] == null)  //如果集合中之前有 null 元素存在则返回 i

                    return i;

        } else {   //非空值插入场景

            for (int i = index; i < fence; i++)

                if (o.equals(elements[i]))

                    return i;

        }

        return -1;

    }

indexOf() 这个方法的作用是判断需要添加的元素在集合中是否存在,若存在则返回该元素的索引,主要用于去重使用;

如果集合中没有重复元素,则返回-1;下面分析addIfAbsent(e, snapshot)这个方法

 

 

集合add 首个元素为例:

private boolean addIfAbsent(E e, Object[] snapshot) { //e=”beppe1”  snapshot=Object[0]

        final ReentrantLock lock = this.lock;

        lock.lock();   //获取独占锁

        try {

            Object[] current = getArray();  // current=Object[0],当线程并发写入时 获取最新的数组值,这里主要是为了获取最新的数组

            int len = current.length;  //len=0

            if (snapshot != current) {  //说明这里并发操作

                // Optimize for lost race to another addXXX operation

                int common = Math.min(snapshot.length, len);              

for (int i = 0; i < common; i++)

                    if (current[i] != snapshot[i] && eq(e, current[i]))

                        return false;

                if (indexOf(e, current, common, len) >= 0)

                        return false;

            }

            //对数组进行动态扩容  copy 当前数组到 新数组中

            Object[] newElements = Arrays.copyOf(current, len + 1);

//将新元素赋值到新的数组中

            newElements[len] = e;

            setArray(newElements);

            return true;

        } finally {

            lock.unlock();   //解锁

        }

    }

4:remove方法:

public boolean remove(Object o) {

        return al.remove(o);   // al 是一个CopyOnWriteArrayList 对象,这里就是执行CopyOnWriteArrayList的remove方法

    }

public boolean remove(Object o) {

        Object[] snapshot = getArray();

        int index = indexOf(o, snapshot, 0, snapshot.length);

        return (index < 0) ? false : remove(o, snapshot, index);

    }

 

说明:CopyOnWriteArraySet 内部维护的是一个 CopyOnWriteArrayList 数据结构,其原理和CopyOnWriteArrayList 的实现原理是一致的;

posted @ 2019-07-19 17:19  beppezhang  阅读(650)  评论(0编辑  收藏  举报