Java

Difference between ArrayList and CopyOnWriteArrayList

There are four concrete implementation of List interface:

  • Vector
  • ArrayList
  • LinkedList
  • CopyOnWriteArrayList

Different between Vector,ArrayList and LinkedList is quite clear but difference between ArrayList and CopyOnWriteArrayList doesn’t seems to be clear at first glance. Here I am trying to explain between difference between ArrayList and  CopyOnWriteArrayList , with one simple example.As we all know ArrayList is not thread safe so any simultaneous thread can access and modify the content of list simultaneously.Here lies the dangerous, ConcurrentModificationException. When one thread is Iterating over an ArrayList and any other thread(which may be the same thread)  modify the content of list and when we again call next() on the iterator ,we get this exception. Which means that no thread can modify the ArrayList while an Iterator is iterating over this. We can solve this by surrounding the code that try to modify this list in a synchronized block with some lock so that the thread trying to modify the ArrayList wait for the iterator to complete.

This seems simple solution but not a efficient one where there are many threads iteration over an ArrayList because each thread have to wait for a considerable time.

Another possible solution could be to use CopyOnWriteArrayList instead of ArrayList. This is same as ArrayList with one difference. All operations that change the contents of aCopyOnWriteArrayList collection cause the underlying array to be replaced with a copy of itself before the contents of the array are changed. Any active iterators will continue to see the unmodified array, so there is no need for locks. Iterators created by a CopyOnWriteArrayList object cannot change the underlying array. Though these iterators do have methods for changing the underlying collection, their implementations throw anUnsupportedOperationException instead of modifying the underlying collection.

Lets consider first case when we modify an ArrayList while an Iterator is traversing it:

import java.util.*;
import java.util.concurrent.*;
import java.math.*;

class test {
	public final static void main(String args[]) {
		List list = new ArrayList();
		list.add("vivek");
		list.add("kumar");
		Iterator i = list.iterator();
		while (i.hasNext()) {
			System.out.println(i.next());
			list.add("abhishek");
		}
	}
}

Output:

vivek

Exception in thread “main” java.util.ConcurrentModificationExceptionat java.util.AbstractList$Itr.checkForComodification(AbstractList.java:449)

at java.util.AbstractList$Itr.next(AbstractList.java:420)

at test.main(test.java:15)

Explanation:

As we have modified the ArrayList after displaying first element, it will throw a ConcurrentModificationException at when we call next() next time.

 

Now see the same program with CopyOnWriteArrayList:

import java.util.*;
import java.util.concurrent.*;
import java.math.*;

class test {
	public final static void main(String args[]) {
		CopyOnWriteArrayList list = new CopyOnWriteArrayList();
		list.add("vivek");
		list.add("kumar");
		Iterator i = list.iterator();
		while (i.hasNext()) {
			System.out.println(i.next());
			list.add("abhishek");
		}
		System.out.println("After modification:");
		Iterator i2 = list.iterator();
		while (i2.hasNext()) {
			System.out.println(i2.next());
		}
	}
}

Output:-

E:\>java test
vivek
kumar
After modification:
vivek
kumar
abhishek
abhishek

Explanation:

We did not get any ConcurrentModificationExceptionat as CopyOnWriteArrayList keeps a copy of original List and iterate over this. The new value which has been added is merged to copy of orignal array only after Iteration is over.

We can not use iterator of CopyOnWriteArrayList to modify the List.

Lest consider a normal ArrayList and try to modify the list using iterator.

import java.util.*;
import java.util.concurrent.*;
import java.math.*;

class test {
	public final static void main(String args[]) {
		ArrayList list = new ArrayList();
		list.add("vivek");
		list.add("kumar");
		Iterator i = list.iterator();
		while (i.hasNext()) {
			System.out.println(i.next());
			i.remove();
		}
		System.out.println("After modification:");
		Iterator i2 = list.iterator();
		while (i2.hasNext()) {
			System.out.println(i2.next());
			;
		}
	}
}
Output:
vivek
kumar
After modification:
Explanation:
we can use iterator’s method (remove) to modify the list. Now check for CopyOnWriteArrayList
import java.util.*;
import java.util.concurrent.*;
import java.math.*;

class test {
	public final static void main(String args[]) {
		CopyOnWriteArrayList list = new CopyOnWriteArrayList();
		list.add("vivek");
		list.add("kumar");
		Iterator i = list.iterator();
		int j = 0;
		while (i.hasNext()) {
			System.out.println(i.next());
			list.add("abhishek");
			i.remove();
		}
	}
}

Output:-

vivek

Exception in thread “main” java.lang.UnsupportedOperationException

at java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove(CopyOnWr

iteArrayList.java:937)

at test.main(test.java:17)

Explanation:

we cannot use iterator method to modify the elements of CopyOnWriteArrayList

From http://techvivek.wordpress.com

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s