It all depends on where you observe the effects of the calls to doA()
and doB()
from.
If you observe the effects from the same thread as is executing the calls, then you are guaranteed to see them as is there had been no reordering. Reordering is not allowed to change the single-threaded behaviour. If the code as written says that doA()
is called before doB()
, then that is what the thread will observe ... if it is looking. In short, no surprises.
If you observe the effects from a different thread, then that thread is guaranteed to be able to observe a state consistent with the single-threaded case at synchronization points. However if one thread attempts to observe the actions of another thread without proper synchronization, then it may observe the effects of reordering.
So ...
How to prevent statements from being reordered by the JVM
Actually, I don't think that you can. But if you code your (multi-threaded) application correctly, it won't be able to observe the effects of reordering. And if it can't observe the effects, it doesn't make any difference to the behaviour if there is or isn't any reordering.
Do method calls on a volatile variable act as volatile writes?
No.
The calls themselves have no specific synchronizing behaviour, but they are preceded by a volatile read (naturally).
... what I actually need is for other threads to see the effects of doA before those of doB.
Then the code must be written so that there is proper synchronization when the state changed by the respective calls is accessed. Technically, there needs to be proper "happens-before" ordering between the writes on one thread and subsequent reads on other threads ... for all of the state that is affected by the method calls.
No magic. No short-cuts. Just properly written synchronization.