https://www.geeksforgeeks.org/fail-fast-fail-safe-iterators-java/

Fail Fast and Fail Safe Iterators in Java

In this article, I am going to explain how those collections behave which doesn’t iterate as fail-fast. First of all, there is no term as fail-safe given in many places as Java SE specifications does not use this term. I am using fail safe to segregate between Fail fast and Non fail-fast iterators.

Concurrent Modification: Concurrent Modification in programming means to modify an object concurrently when another task is already running over it. For example, in Java to modify a collection when another thread is iterating over it. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw ConcurrentModificationException if this behavior is detected.

Fail Fast And Fail Safe Iterators in Java

Iterators in java are used to iterate over the Collection objects.Fail-Fast iterators immediately throw ConcurrentModificationException if there is structural modification of the collection. Structural modification means adding, removing or updating any element from collection while a thread is iterating over that collection. Iterator on ArrayList, HashMap classes are some examples of fail-fast Iterator.

Fail-Safe iterators don’t throw any exceptions if a collection is structurally modified while iterating over it. This is because, they operate on the clone of the collection, not on the original collection and that’s why they are called fail-safe iterators. Iterator on CopyOnWriteArrayList, ConcurrentHashMap classes are examples of fail-safe Iterator.

How Fail Fast Iterator works ?

To know whether the collection is structurally modified or not, fail-fast iterators use an internal flag called modCount which is updated each time a collection is modified.Fail-fast iterators checks the modCountflag whenever it gets the next value (i.e. using next() method), and if it finds that the modCount has been modified after this iterator has been created, it throws ConcurrentModificationException.

// Java code to illustrate
// Fail Fast Iterator in Java
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
 
public class FailFastExample {
    public static void main(String[] args)
    {
        Map<String, String> cityCode = new HashMap<String, String>();
        cityCode.put("Delhi", "India");
        cityCode.put("Moscow", "Russia");
        cityCode.put("New York", "USA");
 
        Iterator iterator = cityCode.keySet().iterator();
 
        while (iterator.hasNext()) {
            System.out.println(cityCode.get(iterator.next()));
 
            // adding an element to Map
            // exception will be thrown on next call
            // of next() method.
            cityCode.put("Istanbul", "Turkey");
        }
    }
}

Run on IDE

Output :

India
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1442)
at java.util.HashMap$KeyIterator.next(HashMap.java:1466)
at FailFastExample.main(FailFastExample.java:18)

Important points of fail-fast iterators :

  • These iterators throw ConcurrentModificationException if a collection is modified while iterating over it.
  • They use original collection to traverse over the elements of the collection.
  • These iterators don’t require extra memory.
  • Ex : Iterators returned by ArrayList, Vector, HashMap.

Note 1(from java-docs): The fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

Note 2 : If you remove an element via Iterator remove() method, exception will not be thrown. However, in case of removing via a particular collection remove() method, ConcurrentModificationException will be thrown. Below code snippet will demonstrate this:

// Java code to demonstrate remove
// case in Fail-fast iterators
 
import java.util.ArrayList;
import java.util.Iterator;
 
public class FailFastExample {
    public static void main(String[] args)
    {
        ArrayList<Integer> al = new ArrayList<>();
        al.add(1);
        al.add(2);
        al.add(3);
        al.add(4);
        al.add(5);
 
        Iterator<Integer> itr = al.iterator();
        while (itr.hasNext()) {
            if (itr.next() == 2) {
                // will not throw Exception
                itr.remove();
            }
        }
 
        System.out.println(al);
 
        itr = al.iterator();
        while (itr.hasNext()) {
            if (itr.next() == 3) {
                // will throw Exception on
                // next call of next() method
                al.remove(3);
            }
        }
    }
}

Run on IDE

Output :

[1, 3, 4, 5]
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at FailFastExample.main(FailFastExample.java:28)

Fail Safe Iterator

First of all, there is no term as fail-safe given in many places as Java SE specifications does not use this term. I am using this term to demonstrate the difference between Fail Fast and Non-Fail Fast Iterator. These iterators make a copy of the internal collection (object array) and iterates over the copied collection. Any structural modification done to the iterator affects the copied collection, not original collection. So, original collection remains structurally unchanged.

  • Fail-safe iterators allow modifications of a collection while iterating over it.
  • These iterators don’t throw any Exception if a collection is modified while iterating over it.
  • They use copy of original collection to traverse over the elements of the collection.
  • These iterators require extra memory for cloning of collection. Ex : ConcurrentHashMap, CopyOnWriteArrayList

Example of Fail Safe Iterator in Java:

// Java code to illustrate
// Fail Safe Iterator in Java
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.Iterator;
 
class FailSafe {
    public static void main(String args[])
    {
        CopyOnWriteArrayList<Integer> list
            = new CopyOnWriteArrayList<Integer>(new Integer[] { 1, 3, 5, 8 });
        Iterator itr = list.iterator();
        while (itr.hasNext()) {
            Integer no = (Integer)itr.next();
            System.out.println(no);
            if (no == 8)
 
                // This will not print,
                // hence it has created separate copy
                list.add(14);
        }
    }
}

Run on IDE

Output:

1
3
5
8

Also, those collections which don’t use fail-fast concept may not necessarily create clone/snapshot of it in memory to avoid ConcurrentModificationException. For example, in case of ConcurrentHashMap, it does not operate on a separate copy although it is not fail-fast. Instead, it has semantics that is described by the official specification as weakly consistent(memory consistency properties in Java). Below code snippet will demonstrate this:

Example of Fail-Safe Iterator which does not create separate copy

// Java program to illustrate
// Fail-Safe Iterator which
// does not create separate copy
import java.util.concurrent.ConcurrentHashMap;
import java.util.Iterator;
 
public class FailSafeItr {
    public static void main(String[] args)
    {
 
        // Creating a ConcurrentHashMap
        ConcurrentHashMap<String, Integer> map
            = new ConcurrentHashMap<String, Integer>();
 
        map.put("ONE", 1);
        map.put("TWO", 2);
        map.put("THREE", 3);
        map.put("FOUR", 4);
 
        // Getting an Iterator from map
        Iterator it = map.keySet().iterator();
 
        while (it.hasNext()) {
            String key = (String)it.next();
            System.out.println(key + " : " + map.get(key));
 
            // This will reflect in iterator.
            // Hence, it has not created separate copy
            map.put("SEVEN", 7);
        }
    }
}

Run on IDE

Output

ONE : 1
FOUR : 4
TWO : 2
THREE : 3
SEVEN : 7

Note(from java-docs) : The iterators returned by ConcurrentHashMap is weakly consistent. This means that this iterator can tolerate concurrent modification, traverses elements as they existed when iterator was constructed and may (but not guaranteed to) reflect modifications to the collection after the construction of the iterator.

Difference between Fail Fast Iterator and Fail Safe Iterator

The major difference is fail-safe iterator doesn’t throw any Exception, contrary to fail-fast Iterator.This is because they work on a clone of Collection instead of the original collection and that’s why they are called as the fail-safe iterator.

Fail Fast and Fail Safe Iterators in Java的更多相关文章

  1. fail fast和fail safe策略

    优先考虑出现异常的场景,当程序出现异常的时候,直接抛出异常,随后程序终止 import java.util.ArrayList; import java.util.Collections; impor ...

  2. 快速失败(fail—fast)和 安全失败(fail—safe)

    快速失败(fail-fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的结构进行了修改(增加.删除),则会抛出Concurrent Modification Exception. 原理 ...

  3. 【问题】Could not locate PropertySource and the fail fast property is set, failing

    这是我遇到的问题 Could not locate PropertySource and the fail fast property is set, failing springcloud的其他服务 ...

  4. Java集合框架中的快速失败(fail—fast)机制

      fail-fast机制,即快速失败机制,是java集合框架中的一种错误检测机制.多线程下用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除),则会抛出Concurre ...

  5. java中fail-fast 和 fail-safe的区别

    java中fail-fast 和 fail-safe的区别   原文地址:http://javahungry.blogspot.com/2014/04/fail-fast-iterator-vs-fa ...

  6. java fail-fast和fail-safe

    快速失败(fail—fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(如增加.删除等),则会抛出Concurrent Modification Exception. ...

  7. 面试题思考:java中快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?

    一:快速失败(fail—fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除.修改),则会抛出Concurrent Modification Exceptio ...

  8. java中快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?

    一:快速失败(fail—fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除.修改),则会抛出Concurrent Modification Exceptio ...

  9. Java中的fail-fast和 fail-safe 的区别

    在我们详细讨论这两种机制的区别之前,首先得先了解并发修改. 1.什么是同步修改? 当一个或多个线程正在遍历一个集合Collection,此时另一个线程修改了这个集合的内容(添加,删除或者修改).这就是 ...

随机推荐

  1. iptables详解与Centos7 关闭防火墙

    http://www.cnblogs.com/metoy/p/4320813.html CentOS 7.0默认使用的是firewall作为防火墙,使用iptables必须重新设置一下 1.直接关闭防 ...

  2. 在Windows Server 2008 R2中使用web方式修改域用户账户密码

    在Windows的domain环境下,加域的客户端修改账户密码是一件很easy的事情:即使没有加域的客户端如果组织中,使用Exchange邮件系统,借助Exchange的owa也可以轻松修改账户密码. ...

  3. Bootstrap 3之美03-独立行,文字环绕,图片自适应,隐藏元素

    本篇主要包括: ■  添加独立的一行■  文字环绕■  图片自适应■  隐藏元素 添加独立的一行 在id为body的section和id为main的section之间,添加2张图片. 我们发现,新加的 ...

  4. C#实现ATM自动取款机

    本篇用C#实现ATM自动取款机的一些功能.面临的第一个问题是:如何把与自动取款机相关的有形的.无形的方面抽象出来.大致如下: (1)关于用户帐号的类:Account(2)关于银行数据库的类:BankD ...

  5. Android网络通信Volley框架源代码浅析(二)

    尊重原创 http://write.blog.csdn.net/postedit/25921795 在前面的一片文章Volley框架浅析(一)中我们知道在RequestQueue这个类中,有两个队列: ...

  6. 解决hiveserver2报错:java.io.IOException: Job status not available - Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask

    用户使用的sql: select count( distinct patient_id ) from argus.table_aa000612_641cd8ce_ceff_4ea0_9b27_0a3a ...

  7. C++ Primer 学习笔记_72_面向对象编程 --句柄类与继承[续]

    面向对象编程 --句柄类与继承[续] 三.句柄的使用 使用Sales_item对象能够更easy地编写书店应用程序.代码将不必管理Item_base对象的指针,但仍然能够获得通过Sales_item对 ...

  8. easyui input设置为disabled提交后获取不到属性值

    在做网站管理后台的用户修改功能时,由于当前用户修改个人信息时规定用户名不能修改,故使用了input标签的disabled属性,但是在提交数据后却发现用户名显示为空了.后 来一查才知道input设置为d ...

  9. 线程池的corePoolSize、maximumPoolSize和poolSize

    什么是线程池: 为了避免系统频繁的创建和销毁线程,我们可以将创建的线程进行复用.在线程池中总有那么几个活跃的线程,也有一定的最大值限制,一个业务使用完线程之后,不是立即销毁而是将其放入到线程池中,从而 ...

  10. 正则表达式和grep

    本章主要通过一些应用实例,来对正则表达式进行说明. 1.正则表达式 正则表达式就是字符串的表达式.它能通过具有意义的特殊符号表示一列或多列字符串.grep是linux系统下常用的正则表达式工具,可以使 ...