乱弹java并发(三)-- CopyOnWriteArrayList和CopyOnWriteArraySet

CopyOnWriteArrayList是基于“写时复制”策略的线程安全的数组,它的特点是写加锁读不加锁,了解过ConcurrentHashMap的原理之后,再理解它的原理就比较简单了,来看看两个关键方法:

    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();
	}
    }

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

    final Object[] getArray() {
        return array;
    }
从代码中可以看到,在往数组中添加元素时,把整个数组拷贝一份把数据插入到新数组中,然后用新数组代替老数组,这样保证多个线程不会再同一个时间点读到不一致的数据,在插入时加了全局锁,所以多个线程不能同时插入数据,而读操作时完全没有锁的,这里面array时一个volatile变量,这点很关键,在插入操作的最后设置这个volatile变量,由volatile在JMM中的happens-before语义,已及hp的传递性,保证了写操作完成之后,写操作更新的数据对读线程时可见的。和ConcurrentHashMap一样,CopyOnWriteArrayList也只能保证弱一致性。由于CopyOnWriteArrayList写操作要拷贝整个数组,所以整个操作对时间的消耗和对GC产生的压力都是比较可观的,而读操作由于无锁,所以读操作比较高效而且读线程之间不会发生阻塞,所以这个结构适用于读操作远远多于写操作的场景。

CopyOnWriteArraySet完全时基于CopyOnWriteArrayList来实现的,这里不再赘述。



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值