Sorry for the non-technical title, but I think it summarizes my question well. If I interpret what I've read correctly, the synchronized block (apart from other consequences) will make all variables updated to/from the main memory (even those which are not accessed explicitly inside the synchronized block, only their "parent"?). E.g. quoting the answer of this stackoverflow question (I took it out of context, I'll return to it later):
The memory barrier applies to all memory references, even unrelated ones.
I need confirmation whether I interpret this correctly. I've 2 threads (threadA, threadB). Consider the following code:
public class SomeClass {
private final Object mLock = new Object();
private int[] anArray;
public void initA() {
synchronized(mLock) {
...
anArray = new int[...];
operationA();
}
}
public void operationA() {
synchronized(mLock) {
// Manipulating the ELEMENTS of anArray,
// e.g. in loops, etc.
anArray[i] = ...
}
}
public int[] getterB() {
synchronized(mLock) {
return anArray;
}
}
}
getterB()
is called from ThreadB, initA()
and operationA()
are called from ThreadA. (Note that initA()
is called even before ThreadB is created, so only getterB()
and operationA()
are concurrent.) Also note that I've a good reason not to return a copy of the array in getterB()
(no, threadB doesn't want to change its elements; the reason is an external requirement for my software that is not relevant now).
threadB does this:
int[] anArray = aSomeClass.getterB(); // aSomeClass is an instance of SomeClass
if (anArray[i] == n) { ....... } // various operations
...
// various other operations that read the elements of anArray
As you can see, in getterB()
, only the anArray
reference is accessed within the memory barriers, and not the array values themselves. My questions:
Will threadB see the most up-to-date array element values? (i.e. are the elements themselves updated too from main memory in
getterB()
?)The quoted statement mentioned that unrelated cached copies are updated from main memory too. I am not 100% how to intepret this unrelated (unrelated to the variable used for locking? or unrelated to the entire synchronized block?). I know I took the quote out of context, and since it's a different stackoverflow question, I've added a comment there. So I appreciate if that question of mine is answered there (or here -- I don't care).
Is there any difference in the answer if
anArray
is an array of Objects (and not of primitive types)? Going even further, what if it's not an array, but a class that contains references to other classes? (i.e. an object that refers to other objects, and I access the contained objects through the object returned bygetterB()
). Will threadB use up-to-date copies of these contained references, or may it use its own local cached copies (sincegetterB()
only updated their container object, but not the contained references themselves)?.