考虑代码片段
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或处于某些非预期状态。这是因为,即使taskArray
是volatile
,并且对该数组的读取将确保该数组本身的适当可见性,但这不能确保对象oneTask
内部状态的可见性。 最佳答案
volatile
关键字仅保护字段taskArray
,它是对Object []的引用。每当您读取或写入此字段时,它将具有一致的顺序。但是,这不会扩展到引用的数组,也不会扩展到该数组引用的对象。
您最有可能要改用AtomicReferenceArray。