copyonwritelist源码理解

本文详细解析了CopyOnWriteArrayList的实现原理,介绍了其如何利用ReentrantLock和数组复制来确保线程安全,并解释了为何get方法不需要加锁。

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

ArrayList 的一个线程安全的变体,其中所有可变操作(add、set 等等)都是通过对底层数组进行一次新的复制来实现的。

上面这句话是官方jdk里写的 其实就是copyonwritelist是一个安全类 每次都是通过复制来实现线程安全

打开copyonwritelist的源码

   /** The lock protecting all mutators */
    final transient ReentrantLock lock = new ReentrantLock();

    /** The array, accessed only via getArray/setArray. */
    private transient volatile Object[] array;

发现了这两个成员变量 从注释上来看 copyonwritelist中的数据主要就是存储在这个array中 加上volatile是让多个线程可见

而ReentrantLock 则是使用了显示锁

我们先看看add方法

   /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    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();
        }
    }

这个可以看到 这个方法在替换整个arr数组 整个方法进行使用了显示锁进行锁定

而我们的get方法则不会进行锁定 这是为什么呢

因为每次调用get的时候对象都是不变的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值