前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 18 - fail fast与fail safe

Java 18 - fail fast与fail safe

作者头像
Reck Zhang
发布2021-08-11 12:18:07
2620
发布2021-08-11 12:18:07
举报
文章被收录于专栏:Reck ZhangReck Zhang

fail fast与fail safe

定义

fail fast

在用迭代器遍历集合对象的时候, 如果遍历过程对集合对象的内容进行了修改(添加, 删除), 那么会抛出ConcurrentModificationException.

因为迭代器在遍历时直接访问集合中的内容, 并且在遍历过程中使用modCount, 集合在遍历期间如果内容发生变化了, 那么就会改变modCount值. 每当迭代器使用hashNext()/next()遍历下一个元素的时候, 都会检测modCount变量是否为expectedModCount, 如果是正常返回, 否则抛出异常.

抛出异常的条件是检测到modCount != expectedModCount, 如果发生变化时修改了modCount同时有设置了expectedModCount, 那么异常不会抛出. 所以不能依赖异常的抛出来进行并发操作.

我们以ArrayList里的remove函数为例:

代码语言:javascript
复制
public E remove(int index) {
    RangeCheck(index);

    modCount++;
    E oldValue = (E) elementData[index];

    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index, numMoved);
    elementData[--size] = null;

    return oldValue;
}

无论是add(), remove()还是clear(), 只要是修改了集合中的元素个数, 都会改变modCount, 再接下来的遍历中, 就会导致异常的抛出.

fail safe

我们以CopyOnWriteArrayList为例. 这种容器实现了读写的分离, 读操作是在原始数组中进行, 写操作是在一个复制的数组上进行. 写操作需要枷锁, 防止并发写入导致数据丢失. 写结束后将原数组指向到新的数组.

代码语言:javascript
复制
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();
    }
}

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

CopyOnWriteArrayList适用于读多写少的场景, 但是缺点在于每次复制数组的开销的数据的不一致. 因此不适用于对内存敏感和实时性要求高的场景.

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-07-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • fail fast与fail safe
    • 定义
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
    http://www.vxiaotou.com