考虑代码片段

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 ?

   }

}

问题:关于对象oneTask的内存可见性,Object oneTask = localTasksArray[someindex];操作安全吗?
oneTask是否有可能显示为null或处于非预期的其他状态?

我的想法是:

线程2可能会看到oneTask为null或处于某些非预期状态。这是因为,即使taskArrayvolatile,并且对该数组的读取将确保该数组本身的适当可见性,但这不能确保对象oneTask内部状态的可见性。

最佳答案

volatile关键字仅保护字段taskArray,它是对Object []的引用。每当您读取或写入此字段时,它将具有一致的顺序。但是,这不会扩展到引用的数组,也不会扩展到该数组引用的对象。

您最有可能要改用AtomicReferenceArray。

09-08 05:49