Saturday 15 April 2017

Difference between synchronized ArrayList and CopyOnWriteArrayList in Java?

Difference between synchronized ArrayList and CopyOnWriteArrayList in Java?


Though both synchronized ArrayList and CopyOnWriteArrayList provides 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 know that ArrayList is not synchronized, so you cannot directly use it in a multi-threaded environment where you list is accessed and modified by multiple threads. In order to use ArrayList in such 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 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.

Synchronized List vs CopyOnWriteArrayList
Initially, when Java comes with 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 Collections.synchronizedList().

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 bottleneck.  Once Java folks realize this fact they were in need of collections which 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 from 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.

You can also read Core Java Volume 1 - Fundamentals by Cay S. Horstmann to learn more about different collection classes of JDK.
Synchronized ArrayList vs CopyOnWriteArrayList in Java




Now let's see some key differences between these two classes in point format to understand it 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 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 iterator returned by CopyOnWriteArrayList is a fail-safe iterator i.e. it will not throw ConcurrentModifcationException 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 difference between fail-safe and fail-fast iterator in Java.

3) Third and one of the key difference between CopyOnWriteArrayList and ArrayList is performance, especially if ArrayList is mostly used for read only purpose. CopyOnWriteArrayList will likely to outperform synchronized ArrayList if that's the case but if its mix of read and write then stick with older one.

One more thing which you need to consider is the size of ArrayList if its big then obviously cost of copying after a write operation is high enough to compensate the cost of locking but if ArrayList is really tiny then you can still use CopyOnWriteArrayList.
Difference between CopyOnWriteArrayList and Synchronized ArrayList in Java

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. Basically, CopyOnWriteArrayList is a better choice if an array is mainly accessed for reading data but if a number of the write operation is high then sticking with synchronized list is a better option because the cost of copying list would outweigh gain made by sacrificing locking.


No comments:

Post a Comment