I came across the following specification which claims that "writes and reads of references are always atomic" http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf.
However, i looked the assembly code generated by both open jdk's JVM and sun jdk's JVM (with PrintAssembly support) for the following code,

Any thread in our program will see either the original values of both s and i, or the new values of both s and i.

Similarly, the JVM can use whatever synchronization features C++ provides to ensure that when it executes a reference write, any other thread in the JVM will see it atomically. It doesn't have to actually BE atomic down to the lowest level; it only has to be atomic at the level of the code in question--in this case, the code of the JVM. As long as the JVM does that, there's no way our Java code can see it as non-atomic. A million steps will look like one to our Java code.

I can see your point with synchronization and AtomicReference. I haven't seen the assembly language code for those objects (mutex or whatever) but i think its safe to assume that assembly code (of Java using synchronization) will have additional instructions to check for lock.
The part i don't understand is why this in-built synchronization of JVM for references doesn't translates to an assembly instruction?

Do you have any idea about the JVM code which provides this in-built synchronization for assignment references?
I would like to explore more on that. Thanks.

I removed further assembly for the sake of readability, and the assembly clearly has the logic to ensure mutual exclusion of the critical section, it acquires the lock and then tries to execute the critical section.

Having seen this, it is only fair to expect similar assembly code for JVM's in-built synchronization for reference assignment, which isn't the case (as per my first post). Can anyone clarify this?

sa**** wrote:
It uses two instructions mov %rdx, %r8 and mov %r8d, 0x10(%rsi). So how can this be atomic?
What if the CPU's context changed after the first instruction?

That is not what the spec means by atomic. Assignment is atomic in the sense that when we have e.g. a 32-bit JVM, the four bytes that comprise a pointer are all written into memory atomically. So that if the variable originally contains

0x11223344

and we assign

0xaabbccdd

to it, any thread that is reading the variable at the same time will get either the old value or the new value, but never e.g. 0x1122ccdd. There are two mov instructions, and while the entire copy operation is not atomic, the read is, and the write is.

The same is not true for e.g. long integers and doubles. If you do a similar assignment to a long, another thread can read a value that is half old, half new value.

sa**** wrote:
Thanks, that clarified. I was in a need to make sure the entire copy (from source) and write (to destination) is synchronized.
AtomicReference solves that purpose.

You don't need AtomicReference in order to make reference reads and writes atomic. They always are. By definition.

AtomicReference is useful for atomic test-and-set semantics, and for ensuring that a thread's write goes to main memory immediately instead of possibly being held in the thread's local cache. But you don't need to to make a read or a write atomic.

Now, when you talk about the "entire copy", if you mean that when you do X = Y;, you want the read from X and the write to Y to both be contained as a single atomic unit, then AtomicReference doesn't help you with that.

Thanks, that clarified. I was in a need to make sure the entire copy (from source) and write (to destination) is synchronized.
AtomicReference solves that purpose.

You are using three different concepts here as though they were the same thing.

1. Writes of references are atomic in the JVM in the sense that writes of longs are not. The entire reference is written in one indivisible operation. A long by contrast is written in two or more operations, so it's theoretically possible for anther thread to see half the old value and half the new value, bit wise speaking.

2. Synchronization ensures that only one thread can execute any of a set of given blocks of code at a time, where all the blocks synchronize on the same object.

3. AtomicReference provides a means to conditionally change a reference from one known value to another if it contains the known value.

These three things have very little to do with each other, and specifically neither (2) nor (3) is necessarily used to implement (1).

Now, when you talk about the "entire copy", if you mean that when you do X = Y;, you want the read from X and the write to Y to both be contained as a single atomic unit, then AtomicReference doesn't help you with that.

Yes, i too thought so (and was about to settle on synchronization) until i saw AtomicReference's assembly translation,

Now, when you talk about the "entire copy", if you mean that when you do X = Y;, you want the read from X and the write to Y to both be contained as a single atomic unit, then AtomicReference doesn't help you with that.

Yes, i too thought so (and was about to settle on synchronization) until i saw AtomicReference's assembly translation,
public void set(Test ref)
There is a logic to test before entering the section to read from source and write to destination,

I'm not going to waste my time trying to read that assembly, and I don't know what point you're trying to make. However, what I said is correct. Specifically, if I call:

myAtomicRef.set(X);

then there are at least two steps that have to happen:

1. Read the value in reference variable X.
2. Write that value into the AtomicReference's member variable.

Step 1 is atomic.
Step 2 is atomic.

The combination of steps 1 and 2 is not atomic, and the only way to make it atomic is to synchronize every access to X and ever use of that AtomicReference (or to provide the equivalent of that syncing using java.util.concurrent.Lock, etc.). Although typically there's no need for that to be atomic.

And if hotspot has not inlined that method call (and I don't even know if that's the kind of optimization it would perform), then there are several more steps: Create a stack frame; read X; put it into its spot on the frame; put the PC into its spot on the frame; jump to the entry point of the method; read X off the stack frame; write X into the member variable; restore the PC to its previous value; drop the stack frame.

So either you are mistaken, or you and I are talking about two completely different things. Possibly both.