• 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的语义.

  • 相关阅读:
    初学C#线程
    初学C#线程二
    JQuery Ajax
    算法测试
    个人报告
    202120221课程设计第三周进展
    socket测试3
    202120221课程设计任务理解与分工
    嵌入式基础
    202120221课程设计第四周进展
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/9434358.html
Copyright © 2020-2023  润新知