Informally, it is not allowed. This is known as the "roach motel model"
http://jeremymanson.blogspot.com/2007/05/roach-motels-and-java-memory-model.html
Particularly, an action cannot be moved across a synchronization block.
However, formally, JMM does not speak in terms of reordering. In your example, we can only reason that,
either the sync block 1 is before the sync block 2 in the total synchronization order, therefore
r2=A
happens-beforeA=2
;r2
must be 0. But there are no constraints betweenB=1
andr1=B
;r1
can be 0 or 1.or the other way around.
r1
must be 0,r2
can be 0 or 2.
So the program still contains data race; nontheless, we can reason that (r1,r2)
can only be (0,0), (1,0), (0,2); it is impossible to be (1,2)