Wednesday, 2 March 2016

Difference between ArrayList and CopyOnWriteArrayList in Java

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 difference between the CopyOnWriteArrayList and ArrayList.

ArrayList Vs CopyOnWriteArrayList in Java

  1. First and foremost difference 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).

  2. 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.

  3. 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

  1. Difference between HashMap and ConcurrentHashMap in Java
  2. Difference between CountDownLatch and CyclicBarrier
  3. Difference between ReentrantLock and Synchronized
  4. CopyOnWriteArraySet in Java
  5. Semaphore in Java concurrency
  6. Java Concurrency interview questions

You may also like -

1 comment:

  1. Thanks for the informative article. This is one of the best resources I have found in quite some time. Nicely written and great info. I really cannot thank you enough for sharing.
    Regards,
    Camellia
    SAP Training in Chennai

    ReplyDelete