Thursday, January 19, 2017

Can we make an Array or ArrayList volatile in Java?

This is one of the many interesting multi-threading questions I have shared in my post 50 multi-threading interview questions. Yes, you can make an array volatile in Java, there is no problem with that, neither compiler will flag any error not JVM will throw any exception but the tricky part is why you want to make an array volatile and what is the effect of making an array volatile in Java? In order to answer this question you must be familiar with both volatile modifier and Java memory model, otherwise, it would be difficult to answer, and that's why it's also one of the trick questions from Java interviews. Before answering this question in detail, let's first revise what is a volatile keyword in Java and what kind of guarantee it provides in the context of multithreading and concurrency.

What is a volatile modifier in Java?

The volatile is a modifier in Java which only applies to member variables, both instance and class variables and both primitive and reference type. It provides the happens-before guarantee which ensures that a write to a volatile variable will happen before any reading. This ensures that any modification to volatile object or primitive type will be visible to all threads i.e. it provides the visibility guarantee.

The volatile modifier also provides ordering guarantee because the compiler cannot re-order any code or operation which involves volatile variables (primitive and objects), but what is perhaps more important to know and remember is that volatile variable doesn't provide atomicity (except for write to the volatile double variable) and mutual exclusion, which is also the main difference between volatile and synchronized keyword.

There are certain restrictions with volatile keyword e.g. you cannot make a member variable both final and volatile at the same time, but you can make a static variable volatile in Java.

If you want to learn more about the volatile variable in Java, I suggest reading Java Concurrency in Practice, which provides more thorough and complete introduction and application of volatile modifier in Java.

Can we make array volatile in Java?

Now, coming back to the original question, can we make an array volatile in Java? The answer is, Yes, you can make an array (both primitive and reference type array e.g. an int array and String array) volatile in Java but only changes to reference pointing to an array will be visible to all threads, not the whole array. What this means is that suppose you have a reference variable called primes as shown below:

protected volatile int[] primes = new int[10];

then if you assign a new array to primes variable, change will be visible to all threads, but changes to individual indices will not be covered under volatile guarantee i.e.

primes = new int[20];

will follow the "happens-before" rule and cause memory barrier refresh, but following code will not do so

primes[0] = 10;
primes[1] = 20;
primes[2] = 30;
primes[3] = 40;

This means, if multiple threads are changing individual array elements e.g. storing updates, there won’t be any happens-before guarantee provided by the volatile modifier for such modification. So, if your use-case is to provide memory visibility guarantee for individual array elements than volatile is not the right choice. You must rely on other synchronization and a thread-safety mechanism to cover this case e.g. synchronized keyword, atomic variables, or ReentrantLock.

Can we make an Array or ArrayList volatile in Java?

On a similar note, sometimes instead of an array, Interviewer put the collection i.e. they will ask can you make a collection variable volatile in Java or not e.g. an ArrayList or HashMap. The answer is same, of course, you can make a reference variable pointing to a Collection volatile in Java, but the happens-before guarantee will only be provided if the value of that reference variable is changed e.g. you assign a new collection to it.

Any modification done on actual collection object e.g. adding or removing elements from ArrayList will not invoke happens-before guarantee or memory barrier refresh. 

If you are curious to learn more about volatile variables and how they work in Java, I strongly suggest you reading Java Concurrency in Practice, perhaps the best book to learn and understand concurrency fundamentals in Java. 

That's all about whether we can make an array volatile in Java or not. Yes, you can make array volatile but that will only cover change to the reference variable pointing to an array, it will not cover changes in individual array elements.

Btw, if you are wondering if Java Concurrency in Practice is still relevant in the age of Java 8 or not then don't forget to read my post, Is Java Concurrency in Practice still valid in the era of Java 8? There I have explained why it is still the best book to learn fundamentals of concurrency in Java.

Thanks for reading this article, if you like this article then please share with your friends and colleagues. If you have any suggestion, correction or any question then please drop a note and I'll take a look.

Further Learning
Java Fundamentals Part 1,2
Java Concurrency in Practice
Applying Concurrency and Multi-threading to Common Java Patterns

No comments :

Post a Comment