Reputation: 180
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
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
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