Difference between synchronized ArrayList and CopyOnWriteArrayList in Java?

What is the difference between a CopyOnWriteArrayList and a Synchronized ArrayList is one of the popular Java interview questions, particularly for beginners with 1 or 2 years of experienced programmers. Though both synchronized ArrayList and CopyOnWriteArrayList provide you thread-safety and you can use both of them when your list is shared between multiple threads, there is a subtle difference between them, Synchronized ArrayList is a synchronized collection while CopyOnWriteArrayList is a concurrent collection. What does this mean? It means is that CopyOnWriteArrayList is designed keeping concurrency in mind and it is more scalable than synchronized ArrayList if the list is primarily used for reading. 

You may know that ArrayList is not synchronized, so you cannot directly use it in a multi-threaded environment where your list is accessed and modified by multiple threads. In order to use ArrayList in such an environment, you need to first get a synchronized list by calling Collections.synchronizedList().

This list achieves thread-safety by locking the whole collection, which means if one thread is reading from the List and the other is also reading from a list, they will go one by one, but you know that multiple threads can read from an object without any issue.

The CopyOnWriteArrayList leverages this knowledge and provides reading without a lock, which means a much better performance if there are more reader threads and write is happening quite low. In short, the main difference between synchronized ArrayList and CopyOnWriteArrayList comes from the fact how they achieve thread safety and how scalable they are.




Difference in Synchronized List vs CopyOnWriteArrayList

Initially, when Java comes with the Collection framework, instead of variants of classes they provide wrappers using java.util.Collections class, for example, if you need a read-only ArrayList, you can get it by calling Collections.unmodifiableList().

Similarly, if you need a synchronized list you can get by calling the  Collections.synchronizedList() method in Java.

This has worked well in past but with time Java applications get more sophisticated and when these classes are exposed in truly concurrent environments, they prove to become bottlenecks.  

Once Java folks realize this fact they were in need of collections that are more scalable and can give more performance if used in a multi-threaded environment and then comes Java 5 with the new set of collection classes called Concurrent Collections.

This library includes concurrent alternatives of most popular collections like ConcurrentHashMap for Hashtable and CopyOnWriteArrayList for ArrayList. They are specifically designed for concurrency and that's why they achieve thread safety in a more sophisticated way than just locking the whole collection.

I have described these and many more differences between them in my earlier post about the difference between concurrent collections and synchronized collections. All the differences which I have mentioned there equally apply when you look for the difference between CopyOnWriteArrayList and Synchronized ArrayList in Java.

Difference between CopyOnWriteArrayList and Synchronized ArrayList in Java



Now let's see some key differences between these two classes in point format to understand them better :

1. First difference between Synchronized ArrayList and CopyOnWriteArrayList comes from the fact how they achieve thread safety. Synchronized List locks the whole list to provide synchronization and thread-safety, while CopyOnWriteArrayList doesn't lock the list and when a Thread writes into the list it simply replace the list by copying. 

This way it provides concurrent access to the list to multiple threads without locking and since read is a thread-safe operation and no two thread writes into the list anytime.

2. The second difference between them comes from the fact how their iterator behave. The Iterator returned from synchronized ArrayList is a fail-fast but the iterator returned by CopyOnWriteArrayList is a fail-safe iterator.

This means it will not throw ConcurrentModificationException even when the list is modified when one thread is iterating over it. If you want to learn more about fail-safe and fail-fast iterator, I suggest you read my earlier post understanding the difference between fail-safe and a fail-fast iterator in Java.

3. Third and one of the key differences between CopyOnWriteArrayList and ArrayList is performance, especially if ArrayList is mostly used for read-only purposes. CopyOnWriteArrayList will likely outperform synchronized ArrayList if that's the case but if it's a mix of reading and writes then stick with the older one.

One more thing which you need to consider is the size of ArrayList if it's big then obviously the cost of copying after a write operation is high enough to compensate for the cost of locking but if ArrayList is really tiny then you can still use CopyOnWriteArrayList.

That's all about the difference between synchronized ArrayList and CopyOnWriteArrayList in Java. In this tutorial, you have learned key differences between them and understood when to use them. 

In short, CopyOnWriteArrayList is a better choice if an array is mainly accessed for reading data but if the number of the write operation is high then sticking with a synchronized list is a better option because the cost of copying list would outweigh the gain made by sacrificing locking.


If you are eager to learn the difference between ArrayList and other Collection classes e.g. HashSet, array, and others, then you would love to check out my following articles as well :
  • What is the difference between an array and an ArrayList in Java? (answer)
  • What is the difference between ArrayList and Vector in Java? (answer)
  • The difference between LinkedList and ArrayList in Java? (answer)
  • What is the difference between HashSet and ArrayList in Java? (answer)
  • What is the difference between ArrayList and HashMap in Java? (answer)
If you are in doubt use CopyOnWriteArrayList over synchronized ArrayList in Java. This will perform better in most cases. 

And, now one question for you, What is the drawback of using CopyOnWriteArrayList in Java? Why people still prefer ArrayList over CopyOnWriteArrayList in Java?

2 comments:

  1. I think your point 3 is confusing. If there is a mix and read, which one should be used?
    So which one is better for read only?

    ReplyDelete
    Replies
    1. For read only purpose, CopyOnWriteArrayList is better because it's concurrent but for read + write, synchronized ArrayList is better.

      Delete

Feel free to comment, ask questions if you have any doubt.