class A {
public synchronized void myOneMethod() {
// ...
}
}
class B extends A {
public synchronized void myOtherMethod() {
// ...
}
}
// ...
B myObject;
// ...
myObject.myOneMethod(); // acquires lock
myObject.myOtherMethod(); // same lock?
How I understand the synchronization model, I'd say that yes, it does, because the lock / monitor is associated with the instance myObject, and it doesn't matter where the method was defined. But am I right? If not, why? If yes, why are you sure, and I'm not? :-)
When a method is declared as synchronized; the thread holds the monitor or lock object for that method's object. If another thread is executing the synchronized method, your thread is blocked until that thread releases the monitor.
Every class in Java has a unique lock which is nothing but a class level lock. If a thread wants to execute a static synchronized method, then thread requires a class level lock.
Locks In Synchronized Methods When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception.
Synchronized methods enable a simple strategy for preventing thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to that object's variables are done through synchronized methods.
Yes, you are right, and you got the explanation right too. Nothing much to add.
Note that if the methods were static, then they would synchronize on different objects, namely their respective classes (A and B).
EDIT: Why am I sure? I don't know, why are you not sure? ;-) myObject
is just one object - there isn't any distinction between the myObject
attributes that come from class A and those that come from class B. (Well, technically you could probably use reflection to find out which are which, so there must be some distinction, but forget about reflection for now. For common operations on the object there's no distinction.)
Yes, synchronized is equivalent to synchronized(this).
To be more precise:
For a class (static) method, the lock associated with the Class object for the method's class is used. For an instance method, the lock associated with this (the object for which the method was invoked) is used.
If you want to be more explicit about your locking, you could do something like this:
class A {
protected final Object mutex = new Object();
public void myOneMethod() {
synchronized (mutex) {
// ...
}
}
}
class B extends A {
public void myOtherMethod() {
synchronized (mutex) {
// ...
}
}
}
In fact, this pattern is recommended by Brian Goetz in Java Concurrency in Practice, section 4.2.1 "The Java monitor pattern". That way you know exactly where your monitor is coming from.
Yes. Java uses "monitors" to implement synchronization, and synchronized methods use the object instance they're called on as monitor, which is obviously the same in this case.
Note that this is NOT true for static methods! There, the class instance of (I think) the declaring class is used, which would not be the same one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With