CopyOnWriteList

数据结构-CopyOnWriteList

` CopyOnWriteList 是线程安全的List版本之一,CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性。



前言

`


提示:以下是本篇文章正文内容,下面案例可供参考

一、类的关系及主要属性

在这里插入图片描述

二、具体属性及方法解释

1.array

volatile 修饰,保证每次拿到都是最新值,volatile表示直接从主存中获取,别的线程如果更新了 arrary,也会将array 更新到主存中。

 private transient volatile Object[] array;

2.get(index)

直接返回数组中的对象

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

3.set(int index,Element element)

大致流程

  1. 用synchronized 加锁,
  2. 获取原数组中index的valve (oldValue)
  3. 判断oldValue 与element 是否相等
  4. 如果不等,则clone原数组。并更新index的值为element,然后更新clone数组
    如果相等则返回 oldeValue (oldValue=element)
public E set(int index, E element) {
        synchronized (lock) {
            Object[] es = getArray();
            E oldValue = elementAt(es, index);

            if (oldValue != element) {
                es = es.clone();
                es[index] = element;
                setArray(es);
            }
            return oldValue;
        }
 }

4.add(E e)

大致流程

  1. 用synchronized 枷锁
  2. getArray() 获取原始数组 es
  3. 获取es 的长度,并将es 拷贝到 es.length+1 到新数组中,并将array=新数组
public boolean add(E e) {
        synchronized (lock) {
            Object[] es = getArray();
            int len = es.length;
            es = Arrays.copyOf(es, len + 1);
            es[len] = e;
            setArray(es);
            return true;
        }
    }

三.问题

1.更新数组为何要copy 一个新数组?

别忘了读操作,读操作是没有加锁的。为了读的高效率。读操作直接在原始数组上读取。不用等新数组更新完 再读区。所以CopyOnWrite适合读多写少的情况。

2.更新操作为何要使用synchronized?

防止其他写线程的影响。所以说如果是读少写多的情况,就是不适合使用CopyONWirte*,因为写会加锁,性能不好。

3.CopyOnWrite的缺点

1.内存占用大

每次add()、set()、remove()这些增删改操作都要复制一个数组出来。

2.数据一致性弱

CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性。
比如 thread_0调用get 的同时,thread_1 正在set(), thread_0读到是旧值。
再比如 迭代原始时,别的线程调用了set,remove,add,也只会遍历旧值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值