For example I have a class with 2 counters (in multi-threaded environment):
public class MyClass {
private int counter1;
private int counter2;
public synchronized void increment1() {
counter1++;
}
public synchronized void increment2() {
counter2++;
}
}
Theres 2 increment operations not related with each other. But I use same object for lock (this).
It is true that if clients simultaneously calls increment1() and increment2() methods, then increment2 invocation will be blocked until increment1() releases the this monitor?
If it’s true, does it mean that I need to provide different monitor locks for each operation (for performance reasons)?
If they’re called on the same instance, then yes.
Only you can know that. We don’t know your performance requirements. Is this actually a problem in your real code? Are your real operations long-lasting? Do they occur very frequently? Have you performed any diagnostics to estimate the impact of this? Have you profiled your application to find out how much time is being spent waiting for the monitor at all, let alone when it’s unnecessary?
I would actually suggest not synchronizing on
thisfor entirely different reasons. It’s already hard enough to reason about threading when you do control everything – but when you don’t know everything which can acquire a monitor, you’re on a hiding to nothing. When you synchronize onthis, it means that any other code which has a reference to your object can also synchronize on the same monitor. For example, a client could use:This can lead to deadlocks, performance issues, all kinds of things.
If you use a
private finalfield in your class instead, with an object created just to be a monitor, then you know that the only code acquiring that monitor will be your code.