CopyOnWriteArrayList源码分析

CopyOnWriteArrayList:
+没有初始容量的说法,需要添加元素时长度+1
+涉及添加修改的时候使用ReentrantLock加锁,保证线程安全
+遍历时不能进行删除操作
+迭代使用snapshot快照,没有快速失败过程

//替换
public E set(int index, E element) {

    final ReentrantLock lock = this.lock;
	//先给容器加上锁,只有一个线程能够修改容器里面的元素
    lock.lock();
    try {
		//获取容器
        Object[] elements = getArray();
		//获取容器中需要修改的值(旧值,index对应位置上的值)
        E oldValue = get(elements, index);
		//判断旧值是否和要修改的相等
        if (oldValue != element) {
			//如果不同,则将旧值改为要修改的值
            int len = elements.length;
			//复制一个新容器,将容器中的值copy到新容器中
            Object[] newElements = Arrays.copyOf(elements, len);
			//修改新容器中index对应的元素
            newElements[index] = element;
			//把旧容器用新容器替换掉
            setArray(newElements);
        } else {
			//如果旧值和要修改的值相等,则不修改
            // Not quite a no-op; ensures volatile write semantics
            setArray(elements);
        }
        return oldValue;
    } finally {
        lock.unlock();
    }
}

/- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/

//添加
public boolean add(E e) {

    final ReentrantLock lock = this.lock;
	//先给容器加上锁,只有一个线程能够修改容器里面的元素
    lock.lock();
    try {
		//获取数组
        Object[] elements = getArray();
		//定义一个int型的值,等于这个数组的长度
        int len = elements.length;
		//创建一个新数组,容量为原来的数组容量+1,并copy原来的数组到新数组中
        Object[] newElements = Arrays.copyOf(elements, len + 1);
		//将新值放到新数组的末端
        newElements[len] = e;
		//将旧容器的引用指向新容器
        setArray(newElements);
		//成功后返回一个true
        return true;
    } finally {
        lock.unlock();
    }
}

/- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/

//删除
public E remove(int index) {

    final ReentrantLock lock = this.lock;
	//先给容器加上锁,只有一个线程能够修改容器里面的元素
    lock.lock();
    try {
		//获取数组
        Object[] elements = getArray();
		//定义一个int型的值,等于这个数组的长度
        int len = elements.length;
		//定义一个老值为index对应位置上的值
        E oldValue = get(elements, index);
		//定义一个int型的值numMoved,为原数组长度-index-1
        int numMoved = len - index - 1;
		//如果numMoved等于零,则为原数组最后一个值,直接删除
        if (numMoved == 0)
            setArray(Arrays.copyOf(elements, len - 1));
        else {
			//如果numMove不等于零,则
			//定义一个新数组,长度为原数组 -1
            Object[] newElements = new Object[len - 1];
			//把从0到index位置的就数组的值copy到新数组的位置
            System.arraycopy(elements, 0, newElements, 0, index);
			//把从index+1到微端的置copy到新数组的尾部
            System.arraycopy(elements, index + 1, newElements, index,
                             numMoved);
			//得到一个新数组
            setArray(newElements);
        }
        return oldValue;
    } finally {
        lock.unlock();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值