Sunday, 15 April 2018

Can I declare an array, collection (or) object as volatile?

One of my friend got this interview question recently. Interviewer would like to know; how volatile keyword works on primitive and reference variables. Before dig into further, let me explain below things.
a.   What is volatile keyword
b.   Can I declare an array, collection (or) as volatile?

What is volatile keyword?
When you declare a field as volatile, java ensures that all threads see a consistent value of the variable.


By default, all the threads store a copy of the field in their local memory, to make the application performance efficient. When one thread changes the value of the field that is shared by multiple threads, due to local copy, other threads can’t see the updated value. It leads to data inconsistency.


Let me explain with an example.

package com.sample.app;

class VolatileEx extends Thread {
 boolean flag = true;

 public void run() {
  while (flag) {
  }
  System.out.println("Came out of the loop");
 }

 public static void main(String args[]) throws Exception {
  VolatileEx t1 = new VolatileEx();
  t1.start();
  Thread.sleep(1000);
  t1.flag = false;
  System.out.println("Flag is set to " + t1.flag);
 }
}


When you execute above program, application goes into the infinite loop. Even you set the flag to false, thread keeps using its local copy of flag, which is true. This problem is solved by volatile keyword.  

We can solve above problem using volatile keyword. When you declare a field as volatile, threads do not keep the copy of the variable in its local memory, thread always fetch the field from shared memory (RAM). Whenever thread wants to update the variable value, it reads from the shared memory and update the value, and push back the updated value to the shared memory. No caching is done.

To confirm this, define the variable flag using volatile modifier, and re run the application.

package com.sample.app;

class VolatileEx extends Thread {
 volatile boolean flag = true;

 public void run() {
  while (flag) {
  }
  System.out.println("Came out of the loop");
 }

 public static void main(String args[]) throws Exception {
  VolatileEx t1 = new VolatileEx();
  t1.start();
  Thread.sleep(1000);
  t1.flag = false;
  System.out.println("Flag is set to " + t1.flag);
 }
}


Output

Came out of the loop
Flag is set to false

Can I declare an array (or) collection as volatile?
Yes, you can declare any primitive, reference variables using volatile keyword. You can’t declare a final variable using volatile keyword. It is a compile-time error if a final variable is declared as volatile.

When you declare an array using volatile keyword, the changes to the reference pointing to an array will be visible to all threads, not the whole array.

volatile String[] names = new String[10];

When you assign new array to the reference variable ‘names’, then the changes will be reflected in all the threads.

names[] = new String[20];

When I define like above, then all the threads can see the array 'names' new assignment.


But if multiple threads are updating the elements of names array, then the changes will not be covered under volatile guarantee. You still need to synchronise the array names, to reflect consistent changes.

You may like



No comments:

Post a Comment