CopyOnWriteList-JDK1.8

CopyOnWrite,一个写时复制的技术来保证并发操作的安全,使用这种技术的前提是读大于写.

读读之间相容,

写写之间互斥,

读写操作相容.

实现方法:

在对底层数据进行写的时候,把底层数据复制一份,对新的备份进行写,写完后再让原来数据的指针指向新的数据.以下为JDK1.8-CopyOnWriteList类似代码.

    private static class CopyOnWriteList<E>
    {
        private transient ReentrantLock lock = new ReentrantLock();

        private transient volatile Object array[];

        CopyOnWriteList()
        {
            array = new Object[0];
        }

        Object[] getArray()
        {
            return array;
        }

        void setArray(Object[] objs)
        {
            array = objs;
        }

        int sizeof()
        {
            return getArray().length;
        }

        boolean empty()
        {
            return sizeof() == 0;
        }

        @SuppressWarnings("unchecked")
        E get(int index)
        {
            return (E) getArray()[index];
        }

        boolean set(E e, int index)
        {
            final ReentrantLock lock = this.lock;
            try
            {
                lock.lock();
                Object[] elements = getArray();
                E oldValue = (E) elements[index];
                if (oldValue != e)
                {
                    int length = elements.length;
                    Object[] newElements = Arrays.copyOf(elements, length);
                    newElements[index] = e;
                    setArray(newElements);
                }
                else
                {
                    // 内存的可见性通过volatile的语义来实现,而不是数组的内容
                    setArray(elements);
                }

                return true;
            }
            finally
            {
                lock.unlock();
            }
        }

        boolean add(E e)
        {
            final ReentrantLock lock = this.lock;
            try
            {
                lock.lock();
                Object[] elements = getArray();
                int length = elements.length;
                // Math.min(original.length, newLength)
                Object[] newElements = Arrays.copyOf(elements, length + 1);
                newElements[length] = e;
                setArray(newElements);
                return true;
            }
            finally
            {
                lock.unlock();
            }

        }

    }

注意:

1.锁和底层数据都是transient,锁是基于内存的,所以写入流里没有意义,对于底层的数据,写入也是没有意义,这是一份快照数据.

2.在JDK-CopyOnWriteList底层数组进行增长的时候只+1,所以,会出现大量的复制.

3.在set方法内,即使新加入的元素和oldValue相等,也要setArray,保证volatile的语义.

原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/9434358.html