Sunday, November 22, 2020

Can You 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 types. 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 a volatile object or primitive type will be visible to all threads i.e. it provides the visibility guarantee.



The volatile modifier also provides an 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 keywords like 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 a more thorough and complete introduction and application of volatile modifiers in Java.

And, if you are serious about mastering Java multi-threading and concurrency then I also suggest you take a look at the Java Multithreading, Concurrency, and Performance Optimization course by Michael Pogrebinsy on Udemy.

It's an advanced course to become an expert in Multithreading, concurrency, and Parallel programming in Java with a strong emphasis on high performance.



Can we make an 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, the 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 the 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 then 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, the Interviewer puts 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 the 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 is done on the actual collection objects. 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, and other key multithreading and parallel programming concepts then I strongly suggest you joining Multithreading and Parallel Computing in Java 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 the 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.

I also suggest you read Java Concurrency in Practice, one of the best concurrency book for Java developers. But, 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 the 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 suggestions, corrections, or any questions then please drop a note and I'll take a look.

Further Learning
Multithreading and Parallel Computing in Java
Applying Concurrency and Multi-threading to Common Java Patterns
Java Concurrency in Practice Course by Heinz Kabutz


Other Multithreading and Concurrency Questions you may like
  • What is the difference between thread and process in Java? (answer)
  • The difference between synchronized and ReentrantLock in Java? (answer)
  • How volatile keyword works in Java? (answer)
  • What is the difference between CyclicBarrier and CountDownLatch in Java? (answer)
  • Top 10 Java Concurrency and multi-threading best practices (article)
  • Top 10 Courses to learn Java in-depth (courses)
  • Top 5 Courses to learn Multithreading and Concurrency in Java (courses)
  • 133 Core Java Interview Questions from the last 5 years (see here)
  • 10 Courses to Crack Java Interviews for Beginners (courses)
  • Top 5 courses to Learn Java Performance Tuning (courses)
  • Difference between extends Thread and implements Runnable in Java? (answer)
  • Difference between the start() and run() method of Thread in Java? (answer)
  • Top 50 Java Thread Interview Questions with Answers (list)
  • Top 12 Java Concurrency Questions for Experienced Programmers (see here)
  • Difference between multi-threading and multi-tasking in Java? (answer)
  • Top 5 Books to learn Java Concurrency in-depth (books)
  • What is happens-before in Java Concurrency? (answer)
  • 6 Books to learn Multithreading and Concurrency in Java (books)
  • 10 Advanced Core Java Courses for Experienced programmers (course)

Thanks for reading this article. If you like this article about array and volatile variables in Java then please share it with your friends and colleagues. If you have any suggestions or feedback then please drop a comment. 

P. S. - If you are new to the Java world and want to learn multithreading concepts looking for some free courses to start with then you can also check out this free Java Multithreading course on Udemy. It is a fantastic free online course to learn  Java Multithreading from scratch as well.

3 comments :

deepak said...

Very well explained!:)

Unknown said...

I tried above sample using JDK 1.8 I'm getting Ilegal Modifier for primes variable only final is permitted.
I believe we can not make array as volatile.

javin paul said...

Hello @Unknown, I think you are right, I read that somewhere that this behavior is changed from Java 8, yet to try that but thanks for pointing it out.

Post a Comment