CopyOnWriteArrayList核心代码逐步阅读

文章详细解释了Copy-on-write(COW)策略在并发环境下的应用,特别是Java中的LinkedTransferQueue的transfer()方法如何实现线程间的元素传输。同时,文章还介绍了CopyOnWriteArrayList的构造及添加、替换和删除元素的机制,强调了其在并发场景下的线程安全性以及transient关键字的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

​​
Copy-on-write简称cow,是一种用于集合的并发访问,和安全的优化策略。
可以同时进行写入和读取,在这个过程中,过程不一定是一致的,但结果一定是一致的。
LinkedTransferQueue类的transfer()方法是Java中的内置函数,通常用于将元素传输到正在等待接收的线程中,如果没有线程等待,则它将等待直到线程尽快进入等待状态等待线程到达的元素将被转移到其中。
  E transfer(E e, boolean timed, long nanos) {

            QNode s = null; // constructed/reused as needed
            boolean isData = (e != null);

            for (;;) {//死循环和cpu有关,和吞吐量有关
                QNode t = tail;//尾部节点
                QNode h = head;//头部节点
                if (t == null || h == null)         
                    continue;                       

                if (h == t || t.isData == isData) { //只有一个节点,
                    QNode tn = t.next;
                    if (t != tail)                  // inconsistent read
                        continue;
                    if (tn != null) {               // lagging tail
                        advanceTail(t, tn);         
                        continue;
                    }
                    if (timed && nanos <= 0)        //超时                        
                    return null;
                    if (s == null)
                        s = new QNode(e, isData);//空节点的处理
                    if (!t.casNext(null, s))        // failed to link in
                        continue;

                        advanceTail(t, s);              // swing tail and wait移动尾节点并且等待
                    Object x = awaitFulfill(s, e, timed, nanos);//awaitFulfill的作用是通过自旋、或者阻塞当前线程来等待节点被匹配。
                    if (x == s) {                   // wait was cancelled
                        clean(t, s);
                        return null;
                    }

                    if (!s.isOffList()) {           // not already unlinked
                        advanceHead(t, s);          // unlink if head
                        if (x != null)              // and forget fields
                            s.item = s;
                        s.waiter = null;
                    }
                    return (x != null) ? (E)x : e;

                } else {                

CopyOnWriteArrayList(Collection<? extends E> c)


这个方法是一个构造函数,主要是针对参数类型的转换。可以得到一个按照Collection迭代器,包含Collection内容的列表。
public E set(int index, E element)

该方法主要实现针对特定位置,传入特定参数,将旧的值替换为指定值,返回值为旧的value值。

 public boolean add(E e)

对该集合进行加元素操作,利用Arrays工具类将旧的数组赋值给新数组,并且返回给全局变量。

public void add(int index, E element)

在指定位置替换元素时,是将旧的数组切割成两份,赋值给新数组。
public E remove(int index)

void removeRange(int fromIndex, int toIndex)

public boolean removeAll(Collection<?> c)

public class CopyOnWriteArrayList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    
    final transient ReentrantLock lock = new ReentrantLock();

//“transient关键字的作用是:被transient修饰的变量不参与序列化和反序列化。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的

    
    private transient volatile Object[] array;

    /**
     * Gets the array.  Non-private so as to also be accessible
     * from CopyOnWriteArraySet class.
     */
    final Object[] getArray() {
        return array;
    }

    /**
     * Sets the array.
     */
    final void setArray(Object[] a) {
        array = a;
    }

    
  public CopyOnWriteArrayList(Collection<? extends E> c) {
        Object[] elements;
        if (c.getClass() == CopyOnWriteArrayList.class)
            elements = ((CopyOnWriteArrayList<?>)c).getArray();
        else {
            elements = c.toArray();
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elements.getClass() != Object[].class)
                elements = Arrays.copyOf(elements, elements.length, Object[].class);
        }
        setArray(elements);
    }


    @SuppressWarnings("unchecked")
    private E get(Object[] a, int index) {
        return (E) a[index];
    }

    
    public E get(int index) {
        return get(getArray(), index);
    }

    
    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;
    

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值