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.
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.
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
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.
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.
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.
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 Java specification which has in-depth information on that.
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.
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 have any suggestions or feedback then please drop a comment.
Very well explained!:)
ReplyDeleteI tried above sample using JDK 1.8 I'm getting Ilegal Modifier for primes variable only final is permitted.
ReplyDeleteI believe we can not make array as volatile.
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.
ReplyDelete