user2392631
user2392631

Reputation: 507

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?

Upvotes: 3

Views: 1359

Answers (2)

assylias
assylias

Reputation: 328598

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.

Upvotes: 5

meriton
meriton

Reputation: 70564

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.

Upvotes: 4

Related Questions