• Java
    • JAXB Tutorial
      • What is JAXB
      • JAXB Marshalling Example
      • JAXB UnMarshalling Example
  • Spring Tutorial
    • Spring Core Tutorial
    • Spring MVC Tutorial
      • Quick Start
        • Flow Diagram
        • Hello World Example
        • Form Handling Example
      • Handler Mapping
        • BeanNameUrlHandlerMapping
        • ControllerClassNameHandlerMapping
        • SimpleUrlHandlerMapping
      • Validation & Exception Handling
        • Validation+Annotations
        • Validation+ResourceBundle
        • @ExceptionHandler
        • @ControllerAdvice
        • Custom Exception Handling
      • Form Tag Library
        • Textbox Example
        • TextArea Example
        • Password Example
        • Dropdown Box Example
        • Checkboxes Example
        • Radiobuttons Example
        • HiddenValue Example
      • Misc
        • Change Config file name
    • Spring Boot Tutorial
  • Hibernate Tutorial
  • REST Tutorial
    • JAX-RS REST @PathParam Example
    • JAX-RS REST @QueryParam Example
    • JAX-RS REST @DefaultValue Example
    • JAX-RS REST @Context Example
    • JAX-RS REST @MatrixParam Example
    • JAX-RS REST @FormParam Example
    • JAX-RS REST @Produces Example
    • JAX-RS REST @Consumes Example
    • JAX-RS REST @Produces both XML and JSON Example
    • JAX-RS REST @Consumes both XML and JSON Example
  • Miscellaneous
    • JSON Parser
      • Read a JSON file
      • Write JSON object to File
      • Read / Write JSON using GSON
      • Java Object to JSON using JAXB
    • CSV Parser
      • Read / Write CSV file
      • Read/Parse/Write CSV File – OpenCSV
      • Export data into a CSV File
      • CsvToBean and BeanToCsv – OpenCSV

JavaInterviewPoint

Java Development Tutorials

Fail-Fast and Fail-Safe Iterators in Java

June 6, 2020 by javainterviewpoint Leave a Comment

An iterator enables us to iterate the objects in a collection, and the iterator can be either Fail-Safe or Fail-Fast. The Fail-Fast iterator will throw ConcurrentModificationException whenever we modify the collection during iteration. On the other hand, Fail-Safe iterator will not throw ConcurrentModificationException even when we modify the collection during iteration. In this article, let’s understand the Fail-Fast and Fail-Safe Iterators in Java.

Fail-Fast and Fail-Safe Iterators in Java

Fail-Fast and Fail-Safe Iterators in Java

 

Before getting into the details, let’s take a look into Fail-Fast and Fail-Safe with an example.

ArrayList is an example of a Fail-Fast iterator, and it throws ConcurrentModificationException when the ArrayList is modified during iteration.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class FailFastIterator
{
	public static void main(String args[])
	{
		List al = new ArrayList();
		al.add("1");
		al.add("2");
		al.add("3");
		
		Iterator it = al.iterator();
		while (it.hasNext())
		{
			String val = it.next();
			if (val.equals("1"))
			{
				al.remove(0);
			}
		}
		System.out.println(al);
	}
}

The above code will throw ConcurrentModificationException, as we are removing an item during iteration when the value is equal to 1.

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:907)
	at java.util.ArrayList$Itr.next(ArrayList.java:857)
	at com.javainterviewpoint.FailFastIterator.main(FailFastIterator.java:19)

Let’s take the ArrayList equivalent Fail-Safe collection, which is CopyOnWriteArrayList, and perform the same removal operation and see what happens?

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class FailSafeInterator
{
	public static void main(String[] args)
	{
		List cl = new CopyOnWriteArrayList();
		cl.add("1");
		cl.add("2");
		cl.add("3");

		Iterator it = cl.iterator();
		while (it.hasNext())
		{
			String val = it.next();
			if (val.equals("1"))
			{
				cl.remove(0);
			}
		}
		System.out.println(cl);
	}
}

Even though we are removing an element during iteration, the CopyOnWriteArrayList will not throw any ConcurrentModificationException.

Output:

[2, 3]

Why fail-fast iterator throws ConcurrentModificationException?

Now let’s understand the internals of a fail-fast iterator with ArrayList. The ArrayList or every fail-fast collection class will have flag variable modCount, which gets incremented for every modification done on the collection, be it addition or removal.

Fail-Fast ArrayList modCount

In the ArrayList class the modCount changes for all the modification methods which we call like add(), remove(), fastRemove(), clear(), trimToSize(), ensureExplicitCapacity()… etc.

The ArrayList class has an inner class Itr, which performs the iteration on the ArrayList.

As a first step, this iterator stores the modCount value to expectedModCount, to keep track of the changes.

int expectedModCount = modCount;

During iteration, the iterators expect the expectedModCount value to be the same as the modCount value. It calls the checkForComodification() method to check whether both values are the same.

final void checkForComodification() {
    if (modCount != expectedModCount)
           throw new ConcurrentModificationException();
}

If we have not performed any modification operations on the collection during iteration, then the modCount and expectedModCount will have the same value. Hence, no ConcurrentModificationException occurs.

But when we have made some modifications to the collection during iteration, the expectedModCount value will not be the same as the modCount, and hence it throws ConcurrentModificationException.

Then how to solve this issue?

We can call the remove() method of the iterator, in that case, we will not get any ConcurrentModificationException as it internally reassigns the value of the expectedModCount to the new modCount value.

public void remove() {
	if (lastRet < 0)
    		throw new IllegalStateException();
	checkForComodification();

	try {
    		ArrayList.this.remove(lastRet);
    		cursor = lastRet;
    		lastRet = -1;
    		expectedModCount = modCount;
	} catch (IndexOutOfBoundsException ex) {
    		throw new ConcurrentModificationException();
	}
}

Let’s change our code with the above approach and check

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class FailFastIterator
{
	public static void main(String args[])
	{
		List al = new ArrayList();
		al.add("1");
		al.add("2");
		al.add("3");
		
		Iterator it = al.iterator();
		while (it.hasNext())
		{
			String val = it.next();
			if (val.equals("1"))
			{
				it.remove();
			}
		}
		System.out.println(al);
	}
}

Now our code works fine and produces the below output.

[2, 3]

Why does fail-safe iterator will not throw ConcurrentModificationException?

The fail-safe iterator works on the snapshot of the actual collection, and so any modification to the actual collection will not disturb the iterator.

In the case of CopyOnWriteArrayList, the iterator() method creates a new instance of COWIterator, to which the original collection is passed and a snapshot is taken and used for iteration.

public Iterator iterator() {
	return new COWIterator(getArray(), 0);
}

As we can see that the COWIterator constructor creates a snapshot from the actual collection (elements array) and stores them in a snapshot array.

private COWIterator(Object[] elements, int initialCursor) {
	cursor = initialCursor;
	snapshot = elements;
}

CopyOnWriteArrayList snapshot

In the above image, we can see that the COWIterator performs all the operations on the snapshot array and not on the real collection, and hence It will not throw any ConcurrentModificationException.

Although this type of iterator will not throw ConcurrentModificationException, it has its drawbacks.

  1. It requires additional memory as it is copying the original collection.
  2. The iterator will not reflect the current state of the collection, as the iteration is happening on the snapshot.

In the fail-fast iterator, we are allowed to remove or add an element using the iterator instance. In contrast, in the case of fail-safe iterator because of the copy mechanism, any add or remove operation using the iterator instance will throw UnsupportedOperationException.

Let’s try to remove an element from the CopyOnWriteArrayList with the iterator instance.

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class FailSafeInterator
{
	public static void main(String[] args)
	{
		List cl = new CopyOnWriteArrayList();
		cl.add("1");
		cl.add("2");
		cl.add("3");

		Iterator it = cl.iterator();
		while (it.hasNext())
		{
			String val = it.next();
			if (val.equals("1"))
			{
				it.remove();
			}
		}
		System.out.println(cl);
	}
}

This will produce UnsupportedOperationException

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove(CopyOnWriteArrayList.java:1178)
	at com.javainterviewpoint.FailSafeInterator.main(FailSafeInterator.java:22)

Fail-Fast Vs Fail-Safe Iterators

Let’s put all them into a tabular form

Fail-Fast Iterator Fail-Safe Iterator
Fail-Fast Iterators does not allow us to make any modification to the collection while iterating Fail-Safe Iterators allows us to modify to the collection while iterating
Throws ConcurrentModificationException when the collection is modified Does not throw ConcurrentModificationException when the collection is modified
Uses the original collection for the iteration Uses the snapshot of the collection for the iteration
We are allowed to modify the collection using the iterator instance We are not allowed to modify the collection using the iterator instance
It does not need additional memory as the iteration happens on the original collection Requires additional memory, as it takes a snapshot of the original collection
Example: Iterators of ArrayList, HashMap, LinkedList, Vector Example: Iterators of CopyOnWriteArrayList, ConcurrentHashMap, ConcurrentMap

Happy Learning!!

Filed Under: Java Tagged With: ConcurrentModificationException, Fail-Fast, Fail-Fast and Fail-Safe Iterators, Fail-Safe

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Java Basics

  • JVM Architecture
  • Object in Java
  • Class in Java
  • How to Set Classpath for Java in Windows
  • Components of JDK
  • Decompiling a class file
  • Use of Class.forName in java
  • Use Class.forName in SQL JDBC

Oops Concepts

  • Inheritance in Java
  • Types of Inheritance in Java
  • Single Inheritance in Java
  • Multiple Inheritance in Java
  • Multilevel Inheritance in Java
  • Hierarchical Inheritance in Java
  • Hybrid Inheritance in Java
  • Polymorphism in Java – Method Overloading and Overriding
  • Types of Polymorphism in java
  • Method Overriding in Java
  • Can we Overload static methods in Java
  • Can we Override static methods in Java
  • Java Constructor Overloading
  • Java Method Overloading Example
  • Encapsulation in Java with Example
  • Constructor in Java
  • Constructor in an Interface?
  • Parameterized Constructor in Java
  • Constructor Chaining with example
  • What is the use of a Private Constructors in Java
  • Interface in Java
  • What is Marker Interface
  • Abstract Class in Java

Java Keywords

  • Java this keyword
  • Java super keyword
  • Final Keyword in Java
  • static Keyword in Java
  • Static Import
  • Transient Keyword

Miscellaneous

  • newInstance() method
  • How does Hashmap works internally in Java
  • Java Ternary operator
  • How System.out.println() really work?
  • Autoboxing and Unboxing Examples
  • Serialization and Deserialization in Java with Example
  • Generate SerialVersionUID in Java
  • How to make a class Immutable in Java
  • Differences betwen HashMap and Hashtable
  • Difference between Enumeration and Iterator ?
  • Difference between fail-fast and fail-safe Iterator
  • Difference Between Interface and Abstract Class in Java
  • Difference between equals() and ==
  • Sort Objects in a ArrayList using Java Comparable Interface
  • Sort Objects in a ArrayList using Java Comparator

Follow

  • Coding Utils

Useful Links

  • Spring 4.1.x Documentation
  • Spring 3.2.x Documentation
  • Spring 2.5.x Documentation
  • Java 6 API
  • Java 7 API
  • Java 8 API
  • Java EE 5 Tutorial
  • Java EE 6 Tutorial
  • Java EE 7 Tutorial
  • Maven Repository
  • Hibernate ORM

About JavaInterviewPoint

javainterviewpoint.com is a tech blog dedicated to all Java/J2EE developers and Web Developers. We publish useful tutorials on Java, J2EE and all latest frameworks.

All examples and tutorials posted here are very well tested in our development environment.

Connect with us on Facebook | Privacy Policy | Sitemap

Copyright ©2023 · Java Interview Point - All Rights Are Reserved ·