If I have 2 synchronized methods in the same class, but each accessing different variables, can 2 threads access those 2 methods at the same time? Does the lock occur on the object, or does it get as specific as the variables inside the synchronized method?
Example:
class X {
private int a;
private int b;
public synchronized void addA(){
a++;
}
public synchronized void addB(){
b++;
}
}
Can 2 threads access the same instance of class X performing x.addA(
) and x.addB()
at the same time?
From the Java SE essentials on synchronized methods:
From the Java SE essentials on synchronized blocks:
(Emphasis mine.)
You have 2 variables no-interleaved. So you want to access to each one from different threads at the same time. you need to define the lock not on the object class itself but on the class Object like below (example from the second Oracle link):
The lock accessed is on the object, not on the method. Which variables are accessed within the method is irrelevant.
Adding "synchronized" to the method means the thread running the code must acquire the lock on the object before proceeding. Adding "static synchronized" means the thread running the code must acquire the lock on the class object before proceeding. Alternatively you can wrap code in a block like this:
so that you can specify the object whose lock must be acquired.
If you want to avoid locking on the containing object you can choose between:
Synchronized on the method declaration is syntactical sugar for this:
On a static method it is syntactical sugar for this:
I think if the Java designers knew then what is understood now about synchronization, they would not have added the syntactical sugar, as it more often than not leads to bad implementations of concurrency.
You can do something like the following. In this case you are using the lock on a and b to synchronized instead of the lock on "this". We cannot use int because primitive values don't have locks, so we use Integer.