CopyOnWriteArrayList was added in Java 5 as a thread-safe alternative to ArrayList, which is one of the most used collection along with HashMap. In this post we'll see the differences between the CopyOnWriteArrayList and ArrayList in Java.
ArrayList Vs CopyOnWriteArrayList in Java
- First and foremost difference between CopyOnWriteArrayList and ArrayList is of course thread safety. ArrayList is not thread-safe whereas
CopyOnWriteArrayList is thread-safe and fit for use in multi-threaded environment.
This thread safety in CopyOnWriteArrayList is achieved by making a fresh copy of the underlying array with every mutative operations (add, set, and so on).
Iterator returned by ArrayList is fail-fast. Which means, if the underlying collection is structurally modified in any way except through the iterator's own remove or add methods, it will throw ConcurrentModificationException.
Iterator returned by CopyOnWriteArrayList is fail-safe. Iterators for the CopyOnWriteArrayList uses a reference to the state of the array at the point that the iterator was created. Since any mutation will result in a fresh copy of the underlying array. Thus the array that the iterator has a reference to never changes during the lifetime of the iterator, so interference is impossible and the iterator is guaranteed not to throw ConcurrentModificationException.
Let's see this difference with an example, here we'll have an ArrayList which will be iterated. Simultaneously a new thread is created which will try to add an element to that ArrayList.
public class CADemo { public static void main(String[] args) { List<Integer> numList = new ArrayList<Integer>(); // Adding 5 elements to the set for(int i=1;i<=5;i++) { numList.add(i); } // Creating new thread new Thread(new Runnable(){ @Override public void run() { try { // introducing some delay Thread.sleep(150); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } // add new element to the set numList.add(6); System.out.println("" + numList); } }).start(); // get an iterator Iterator<Integer> itr = numList.iterator(); while(itr.hasNext()){ Integer i = itr.next(); try { Thread.sleep(30); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //itr.remove(); System.out.println("" + i); } } }
Output
1 2 3 4 5 [6] Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at org.netjs.prgrm.CADemo.main(CADemo.java:37)
Here it can be seen that the ConcurrentModificationException is thrown as there is an attempt to add an element to the ArrayList while it is iterated.
Example code with CopyOnWriteArrayList
Now let's changed the ArrayList with CopyOnWriteArrayList.
public class CADemo { public static void main(String[] args) { List<Integer> numList = new CopyOnWriteArrayList<Integer>(); // Adding 5 elements to the set for(int i=1;i<=5;i++) { numList.add(i); } // Creating new thread new Thread(new Runnable(){ @Override public void run() { try { // introducing some delay Thread.sleep(150); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } // add new element to the set numList.add(6); System.out.println("" + numList); } }).start(); // get an iterator Iterator<Integer> itr = numList.iterator(); while(itr.hasNext()){ Integer i = itr.next(); try { Thread.sleep(30); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //itr.remove(); System.out.println("" + i); } } }
Output
1 2 3 4 [1, 2, 3, 4, 5, 6] 5
Here it can be seen that the ConcurrentModificationException is not thrown. Also, since iterator gets its own copy so it doesn't reflect the change made to the CopyOnWriteArrayList while iteration is done.
- Performance wise ArrayList is faster as it is not synchronized and there is no added burden of thread-safety. CopyOnWriteArrayList is comparatively slower and if there are lots of writes by various threads that will degrade the performance of the CopyOnwriteArrayList as there will be copies made per mutation.
That's all for this topic Difference Between ArrayList And CopyOnWriteArrayList in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!
Related Topics
You may also like-