Search code examples
javaarraysthread-safetyvolatilememory-visibility

Volatile array - memory visibility of the elements


Consider the code snippet

class A {

   private Map<String, Object> taskMap = new HashMap<>();
   private volatile Object[] tasksArray ;

   // assume this happens on thread1 
   public void assignTasks() {
     synchronized(taskMap){
         // put new tasks into map
         // reassign values from map as a new array to tasksArray ( for direct random access )
     }

    }

   // assume this is invoked on Thread2
   public void action(){
       int someindex =  <init index to some value within tasksArray.length>;
       Object[] localTasksArray = tasksArray;
       Object oneTask = localTasksArray[someindex];
       // Question : is the above operation safe with respect to memory visibility for Object oneTask ?
       // is it possible that oneTask may appear null or in some other state than expected ?

   }

}

Question : is the operation Object oneTask = localTasksArray[someindex]; safe with respect to memory visibility for Object oneTask ? is it possible that oneTask may appear null or in some other state than expected ?

My thoughts are these :

It is possible that thread2 may see oneTask as null or in some state other than expected. This is because , even though the taskArray is volatile , and a read of this array will ensure proper visibility of the array itself , this does not ensure the visibility of the state internal to the object oneTask.


Solution

  • The volatile keyword only protects the field taskArray which is a reference to an Object[]. Whenever you read or write this field, it will have consistent ordering. However, this doesn't extend to the array referenced nor the objects that array references.

    Most likely you want AtomicReferenceArray instead.