Suppose I have the following code in Java
a = 5;
synchronized(lock){
b = 5;
}
c = 5;
Does synchronized prevent reordering? There is no
Does synchronized prevent reordering?
Partially, see below.
Would assignment to a first happen then to b and then to c?
No. As dcastro pointed out, actions can be moved into synchronized blocks. So the compiler would be allowed to generate code, that corresponds to the following statements:
synchronized (lock){
a = 5;
b = 5;
c = 5;
}
And the compiler is also allowed to reorder statements within a synchronized block, that have no dependency to each other. So the compiler can also generate code that corresponds to the following statements:
synchronized (lock){
c = 5;
b = 5;
a = 5;
}
If I did not have synchronized, the statements can be reordered in any way the JVM chooses right?
Well, I think that's the wrong question, and it's also the wrong way to think about the Java Memory Model. The Java Memory Model is not defined in terms of reorderings. Actually, it's much easier than most people think. Basically, there is only one important rule, that you can find in §17.4.5 in the Java Language Specification:
A program is correctly synchronized if and only if all sequentially consistent executions are free of data races. If a program is correctly synchronized, then all executions of the program will appear to be sequentially consistent.
In other words: If you completely ignore reorderings, and for all possible executions of the program, there is no way that two threads access the same memory location, which is neither volatile nor atomic, and at least one of the actions is a write operation, then all executions will appear, as if there are no reorderings.
In short: Avoid data races, and you will never observe a reordering.