Robin Kreuzer
Robin Kreuzer

Reputation: 180

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?

Upvotes: 2

Views: 92

Answers (2)

Solomon Slow
Solomon Slow

Reputation: 27115

You have not given enough information to answer the question.

Presumably, CODE1, CODE3, and CODE5 access data that is shared with other threads because if they did not, then there would be no point in using synchronized.

So, what would happen if thread B tries to use the shared data after thread A has performed CODE1, but not yet performed CODE3 or CODE5? What would happen if thread B tries to use the shared data after thread A has performed CODE1 and CODE3, but not CODE5? If any bad thing could happen as a result, then you need to perform all three of the CODEs in the same synchronized block, and also, whatever thread B is doing with that same shared data, it also must do it in a similar synchronized(this) block.


If CODE1, CODE3, and CODE5 are fully independent of each other, then my gut reaction would be to use several smaller synchronized blocks---especially so if any of the five CODEs takes any significant amount of time. I like to keep synchronized blocks as short (timewise) as possible.

But if the performance is really critical, then you ought to measure it and prove to yourself which is the better way.

Upvotes: 1

Holger
Holger

Reputation: 298103

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.

Upvotes: 5

Related Questions