fail-fast策略以及fail-safe是什么?

什么是fail-fast?
简单的来说就是优先考虑出现异常的场景,当异常产生时,直接抛出异常,程序终止。
在jcl中的fail-fast?
fail-fast只要是体现在当我们在遍历集合元素的时候,经常会使用迭代器,但在迭代器遍历元素的过程中,如果集合的结构被改变的话,就会抛出异常ConcurrentModificationException,防止继续遍历。这就是所谓的快速失败机制。
这里要注意的这里说的结构被改变,是例如插入和删除这种操作,只是改变集合里的值的话并不会抛出异常。

public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("C++");
        list.add("Python");
        list.add("PHP");
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String str = iterator.next();
            if (str.equals("PHP")) {
                list.remove(str);//因为移除了元素会抛异常
            }
            System.out.println(str);
        }
    }

这种机制最大的作用就在于多线程时保证多线程场景下不产生 “脏读”,一旦有线程在读取另一个线程想要更改就会直接抛出异常,可是直接抛出异常并不是我们想要的结果,应该采用线程安全的集合。
什么是fail-safe?
当我们对集合结构上做出改变的时候,fail-fast机制就会抛出异常。但是,对于采用fail-safe机制来说,就不会抛出异常。这是因为,==当集合的结构被改变的时候,fail-safe机制会在复制原集合的一份数据出来,然后在复制的那份数据遍历。==比如CopyOnWriteArrayList这个juc包下的线程安全集合类,就使用了fail-safe这个策略。

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

以这个集合的add为例,为什么CopyOnWriteArrayList不会抛ConcurrentModificationException异常就在于copy原来的array,再在copy数组上进行add操作,这样做就完全不会影响CopyOnWriteArrayList中的array了。当然像其他的如remove、clear等方法也使用相同的策略。

fail-safe的缺点
从上面的两个核心操作可以看出,fail-safe有一定的缺陷
1.复制时需要额外的空间和时间上的开销。
2.由于都是复制原来的数组,多线程时可能就不能保证遍历的是最新内容。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值