Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 746
Hanno Fietz Avatar asked Mar 09 '09 10:03

Hanno Fietz


People also ask

Does synchronized method lock object?

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.

Which lock is required for synchronized method in Java?

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.

Which object has its lock acquired for the synchronized method?

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.

What is synchronized method in Java?

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.


4 Answers

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

like image 150
David Z Avatar answered Oct 01 '22 10:10

David Z


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.

like image 20
pgras Avatar answered Oct 01 '22 09:10

pgras


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.

like image 34
Julien Chastang Avatar answered Oct 01 '22 10:10

Julien Chastang


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.

like image 36
Michael Borgwardt Avatar answered Oct 01 '22 10:10

Michael Borgwardt