Let's assume that our program has a central point (an instance of a Document class), where all kinds of information are referenced. Now we have two threads. Both threads have access to our "document" and "document" contains a reference to let's say "params" (an object that holds some kind of information). So if we have a reference to "document" we can use "document.params" to get our params object.
Thread 1 does the following:
Params tempParams = document.params; // get a local reference to documents.params
int a = tempParams.a; // read data from params
// thread 1 (this thread) gets interrupted by thread 2
int b = tempParams.b; // read data from params
int c = tempParams.c; // read data from params
Thread 2 does the following:
Params newParams = new Params();
... // fill newParams with new parameters
lock(obj) {
document.params = newParams; // update params in document
}
So the content of "params" is never changed, but if a change is needed a new copy is generated and the reference "document.params" get's updated to the new Params block which is an atomic action.
Now the big question is:
Is it possible that the jitter might optimize the code of thread 1 that way that tempParams is not a memory address but a CPU register? And if Thread 2 updates the document.params reference, there is no reference in memory that points to the old "Params" block, since the reference in Thread 1 is only in a CPU register. And if just in this moment the garbage collector starts, how can it see that the old "Params" block is still in use?
The other question would be: might it happen that the jitter optimizes away the tempParams variable and uses document.params.a/b/c directly. In this case Thread 1 would see the swap of the Params object which is not intended. The use of tempParams shall ensure that Thread 1 access a/b/c from the same Params object that was in document.params when the reference was copied.