Search code examples
javaconcurrencysynchronized

java: one synchronized vs more synchronized around the same code


is one synchronized better than a lot of synchronized?

synchronized(this)
{
   CODE1
   CODE2 // uncritically code, short duration
   CODE3
   CODE4 // uncritically code, short duration
   CODE5
}

VS

synchronized(this)
{
   CODE1
}

CODE2 // uncritically code, short duration

synchronized(this)
{
   CODE3
}

CODE4 // uncritically code, short duration

synchronized(this)
{
   CODE5
}

the following applies: the synchronized blocks so small as possible, like i coded in my secound example.

But is that right in any case? If the uncritcally code snippets a in the duration short enoguh, maybe my program is more performant if i dont lock unlock lock unlock and so on?


Solution

  • The JVM’s optimizer is capable of joining adjacent synchronized blocks if it helps performance, but it can’t do the opposite, as splitting it would change the semantic.

    See the Java SE 6 Performance White Paper, 2.1.2 Lock coarsening

    There are some patterns of locking where a lock is released and then reacquired within a piece of code where no observable operations occur in between. The lock coarsening optimization technique implemented in hotspot eliminates the unlock and relock operations in those situations […]. It basically reduces the amount of synchronization work by enlarging an existing synchronized region.

    the reference to Java 6 shows that this is not even a brand new feature
    So if you know that there’s uncritical code and the entire code works with temporarily releasing the lock (which may have the state altered in-between by other threads), then use multiple synchronized blocks, to tell the JVM and the human readers that CODE2 and CODE4 are not critical.

    This follows the typical pattern of letting the runtime optimizer make the right trade-offs, as it knows more about the actual situation, i.e. hardware and actual application behavior, than us.