Inside Java: Concurrent modification when using collection and iterator

ConcurrentModificationException may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible. This exception is encountered more often in case of collections when one thread is iterating over the collection and other tries to modify it.

This article explains how java detects concurrent modifications to a List with the help of an example. The comments provided along with the code are self explanatory so let us go through the example first:

ConcurrentModificationTest.java

package com.technicalmusings.examples.collection;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
* The class explains how concurrent modification is detected in List.
*/

public class ConcurrentModificationTest {

public static void main(String[] args) {

// Instantiating the list sets the modCount field of list to 0
// modCount is a protected integer variable defined in the AbstractList class.

List<Object> myList = new LinkedList<Object>();

myList.add(new Object()); // modCount incremented to 1
myList.add(new Object()); // modCount incremented to 2
myList.add(new Object()); // modCount incremented to 3

// Getting an iterator sets the value of expectedModCount field
// equal to that of the modCount field of list.

Iterator<Object> itr1 = myList.iterator(); //itr1: expectedModCount = 3
Iterator<Object> itr2 = myList.iterator(); //itr2: expectedModCount = 3

// The first Iterator traverses the list once
itr1.next();

// The second iterator traverses and removes the first element
itr2.next();
itr2.remove();
// In the previous step Itr2 modifies the list and sets the
// expectedModCount field to 4. The modCount field of the list
// has also been now incremented to 4

// The first iterator again tries to traverse the list
itr1.next();

// java.util.ConcurrentModificationException is thrown at this stage
// because itr1 finds its expectedModCount (which is still 3) to be not
// matching with the modCount field of the list
}
}

The ConcurrentModificationTest.java class shown above explains how java works behind the scenes to detect concurrent modification and throw the ConcurrentModificationException in case of a List. List has an integer field modCount, which is incremented each time a structural modification is done in the list. Structural modification includes methods like add, remove, clear etc. The Iterator on the other hand uses another integer field, expectedModCount, to take care of concurrent modifications in the list. Iterator expects both the variables modCount and expectedModCount to be the same. In case the list is modified by any other means the modCount and expectedModCount differs and the exception is thrown.

Advertisements

Java Threads: Thread and Exception Handling

Whenever an uncaught exception occurs in a thread’s run method we get a default exception dump which gets printed on System.err stream. We may not always want to live with this default behavior and might think about logging the exception message in a more sophisticated way or doing something else as per business requirement.

Such custom exception handling can be achieved using the UncaughtExceptionHandler interface of the Thread class. The ThreadGroup class also implements the Thread.UncaughtExceptionHandler interface. The interface has only one method defined, which is:

void uncaughtException(Thread t, Throwable e);

This handler interface is invoked when a thread abruptly terminates due to an uncaught exception. The below excerpt from Java documentation explains the UncaughtExceptionHandler interface:

When a thread is about to terminate due to an uncaught exception the Java Virtual Machine will query the thread for its UncaughtExceptionHandler using Thread.getUncaughtExceptionHandler() and will invoke the handler’s uncaughtException method, passing the thread and the exception as arguments. If a thread has not had its UncaughtExceptionHandler explicitly set, then its ThreadGroup object acts as its UncaughtExceptionHandler. If the ThreadGroup object has no special requirements for dealing with the exception, it can forward the invocation to the default uncaught exception handler.

Thread class has two methods viz. setDefaultUncaughtExceptionHandler() and setUncaughtExceptionHandler(). The setDefaultUncaughtExceptionHandler() which is a static method of Thread class can be used to provide a common exception handler for all the threads. On the other hand setUncaughtExceptionHandler() is a non static method of Thread class which is used to provide handler to a given thread.

The below example shows how to handle the uncaught exception thrown from a Thread:

MyThreadTest.java

package com.technicalmusings.examples.thread;

/**
* The below class creates a thread which is supposed to throw an exception.

* A handler is added to the thread before calling the start method of thread.
* When the thread executes the exception is handled by the handler
* and the custom exception message is displayed on the console.
*/

public class MyThreadTest {

public static void main(String[] args) {

Thread newThread = new Thread(new ThreadWithException());

// Add the handler to the thread object
newThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){

@Override
public void uncaughtException(Thread t, Throwable e) {

System.out.println("ERROR! An exception occurred in " + t.getName() + ". Cause: " + e.getMessage());
}
});

newThread.start();
}
}

/**
* This thread throws a custom exception in its run method.
*/

class ThreadWithException implements Runnable {

@Override
public void run() {
throw new RuntimeException("Application Specific Exception!!");
}
}

Output:

ERROR! An exception occurred in Thread-0. Cause: Application Specific Exception!!

Enjoy Learning,
Kamlesh