java - volatile 数组 - 元素的内存可见性

标签 java arrays thread-safety volatile memory-visibility

考虑代码片段

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 = localTask​​sArray[someindex]; 是否安全? oneTask 是否可能显示为空或处于与预期不同的其他状态?

我的想法是:

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

最佳答案

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

很可能您需要 AtomicReferenceArray。

关于java - volatile 数组 - 元素的内存可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24374189/

相关文章:

java - 调试do-while循环出现多个语句

java - 从Oracle触发器调用Java程序

c++ - 获取数组的长度。编译器错误。

c++ - 多个线程竞相将相同的数据设置为相同的值

java - Java中的原始数据类型是线程安全的吗

java - 在 MobileFirst 服务器(Liberty 服务器)中使用 jax-ws

java - LinkedHashMap removeEldestEntry 删除 2 个元素?

python - 如何增加python中打印的列数?

PHP函数获取数组的前5个值

c# - 如果其他方法正在运行,如何确保某个方法不会被执行?