Java: A synchronized method in the superclass acquires the same lock as one in the subclass, right?

匿名 (未验证) 提交于 2019-12-03 08:35:02

问题:

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? :-)

回答1:

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.)



回答2:

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.



回答3:

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.



回答4:

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.



回答5:

Yes you are correct

When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object. In this case the object is B



回答6:

Just a small addition for people who might be interested in the future..

Additionally remember that locks in Java are reentrant. If they were not this code of yours would result in a deadlock since as you've indicated both operations require the same lock.



回答7:

From the conceptual viewpoint, the mutex integrity of some inheritance scenarios would be broken if synchonized methods of class A would only protect A's data in the context of subclass B. After all, not all of A's data is required to be private.

Imagine that you want to slightly extend the functionality of one method of A while keeping the rest of A's functionality including mutex protection. If A were only protecting itself, you would end up having to override all of A's synchronized methods to lift the original synchronization mechanism to the new subclass. Not very attractive and also not very efficient.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!