Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronized and Code reorder in java

In some link it is given that code reorder inside synchronized block is possible, whereas some other site is telling not possible. Can u please give an example to describe what actually happens in respect of code reordering when synchronized is used?

like image 747
user2392631 Avatar asked Jun 14 '26 11:06

user2392631


2 Answers

There are two possible reorderings:

  • statements before or after the synchronized block may be moved inside the synchronized block (provided they are not in a different synchronized block of course) - it is sometimes called the "roach motel" principle
  • statements inside a synchronized block may be reordered as long as the modification is sequentially consistent (i.e. the effect is not visible from other code that shares a happens-before relationship with the block)

But more importantly: if your code is properly synchronized, these reorderings won't affect the execution of your program, which is all you should care about.

Example (all variables originally at 0):

Thread1:

a=1;
synchronized(lock) {
    b=1;
    c=1;
}
d=1;

Thread2:

synchronized(lock) {
    if (a==1) print(b); // can print 0 or 1
    if (b==1) print(a)/print(c); // always prints 1
    if (b==1) print(d); // can print 0 or 1
    if (d==1) print(a)/print(b)/print(c); // always prints 1
}

In particular, moving d=1 to before c=1 or moving a=1 to after b=1 is allowed as it is not something that Thread 2 would be able to observe, because the synchronized block executed by Thread 1 looks like an atomic operation from Thread 2.

On the other hand, a thread that does not use the same lock would be able to observe these reorderings.

like image 193
assylias Avatar answered Jun 16 '26 23:06

assylias


The runtime may reorder operations as long as happens-before is respected. The spec writes:

It should be noted that the presence of a happens-before relationship between two actions does not necessarily imply that they have to take place in that order in an implementation. If the reordering produces results consistent with a legal execution, it is not illegal.

and

More specifically, if two actions share a happens-before relationship, they do not necessarily have to appear to have happened in that order to any code with which they do not share a happens-before relationship. Writes in one thread that are in a data race with reads in another thread may, for example, appear to occur out of order to those reads.

In particular, if one thread does:

synchronized (lock) {
    x = 1;
    y = 1;
}

and another does:

if (y == 1) System.out.println(x);

there is no happens-before relationship between these threads, and the other thread may observe y to have been assigned before x was, and print 0.

like image 35
meriton Avatar answered Jun 16 '26 23:06

meriton