当前位置: 首页 > 图灵资讯 > java面试题> 金三银四精选java面试题-什么是快速失败(fail-fast)和安全失败(fail-safe)?

金三银四精选java面试题-什么是快速失败(fail-fast)和安全失败(fail-safe)?

来源:图灵教育
时间:2023-11-29 09:38:26
 

 什么是快速失败(fail-fast)和安全失败(fail-safe)?

快速失败 (Fail-Fast) 和安全失败 (Fail-Safe) 是两种处理并发集合操作的不同策略

  1. 快速失败 (Fail-Fast)
    • 在快速失败策略下,如果一个集合在迭代过程中被修改(增加、删除、修改等),迭代器会立即抛出 ConcurrentModificationException 异常,以防止并发修改导致不一致或不可预测的行为。
    • 快速失败迭代器迅速检测到并发修改,因此它能够尽早发现问题,但也可能导致某些操作失败。
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ConcurrentModificationException;

public class FailFastDemo {
    public static void main(string[] args) {
        ArrayList<String> list = new ArrayList<>();

        list.add("Item 1");
        list.add("Item 2");
        list.add("Item 3");

        Iterator<String> iterator = list.iterator();

        while (iterator.hasNext()) {
            String item = iterator.next();
            System.out.println(item);
            
            // 在迭代过程中尝试添加新元素,触发 ConcurrentModificationException 异常
            list.add("New Item");
        }
    }
}
  1. 安全失败 (Fail-Safe)
    • 在安全失败策略下,集合允许迭代过程中进行修改,但不会抛出 ConcurrentModificationException 异常。相反,迭代器会访问集合的一个快照或复制品,以确保不受并发修改的影响。
    • 安全失败迭代器不会阻止并发修改,但可能会在某些情况下返回不一致的数据视图。这允许更多的灵活性,但可能需要额外的开销来维护副本或快照。
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.Iterator;

public class FailSafeDemo {
    public static void main(String[] args) {
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();

        list.add("Item 1");
        list.add("Item 2");
        list.add("Item 3");

        Iterator<String> iterator = list.iterator();

        while (iterator.hasNext()) {
            String item = iterator.next();
            System.out.println(item);

            // 在迭代过程中添加新元素,不会触发异常
            list.add("New Item");
        }
        
        // 迭代结束后,集合已经包含了新添加的元素
        System.out.println("Updated List: " + list);
    }
}

通常情况下,Java 集合框架中的大多数集合类都采用了快速失败策略例如 ArrayList、HashMap 等。这意味着如果在迭代集合时发生并发修改,会立即抛出异常。

一些并发集合类,如 ConcurrentHashMap 和 CopyOnWriteArrayList,采用了安全失败策略。它们允许在迭代过程中进行修改,但不会抛出异常。这对于某些特定的并发应用场景可能更合适。

选择快速失败或安全失败策略取决于应用程序的需求和性能要求。如果并发修改很少发生,或者需要尽早检测到问题,那么快速失败策略可能更适合。如果需要更高的并发性和灵活性,并且可以容忍一些不一致性,那么安全失败策略可能更合适。