0

I’m reading a book regarding to the OCPJP exam. It says

An entire method can be declared synchronized. In that case, when the method declared as synchronized is called, a lock is obtained on the object on which the method is called, and it is releases when the method returns to the caller.

What I got from this phrase;

If there is a class called A, which calls a synchronized method, resides in the class B, is acquiring the lock from an object of class A (which the method is called).

Is it correct or not?

Does it need to acquire the lock from an object of class B? Just like synchronized block using this reference.

Hardik Mishra
  • 14,779
  • 9
  • 61
  • 96
user2486322
  • 847
  • 3
  • 13
  • 31

3 Answers3

2

If there is a class called A, which calls a synchronized method, resides in the class B, is acquiring the lock from an object of class A (which the method is called).

No, in this case object of class B will be used as lock, since the method belongs to Class B

Abimaran Kugathasan
  • 31,165
  • 11
  • 75
  • 105
1

The lock is on the B-object that is used by A. This object can be anywhere, in my example it is in class A, but it could be passed to A through a parameter of the execute()-method.

Imagine this:

public class A{
    public B objectB;

    public void execute(){
        objectB = new B();

        // objectB is synchronized during the execution of the following call, no other        
        // Thread can access ANY synchronized method of objectB or any 
        // synchonized(this) block within objectB in this time
        objectB.syncedMethod();   
    }
}

public class B{
    public synchronized void syncedMethod(){
        //doImportantStuff
    }

    public synchronized void anotherSyncmethod(){
        //do other important stuff
    }
}

The effect is same like synchronizing on "this" inside the method (I guess the resulting Java bytecode will be different, see comments)

public class B{
    public void syncedMethod(){
      synchronized(this){
        //doImportantStuff
      }
    }

    public void anotherSyncmethod(){
        synchronized(this){
         //do other important stuff
        }
    }
}
Chrisport
  • 2,936
  • 3
  • 15
  • 19
  • 1
    If memory serves, `public synchronized ______() {...}` is actually just syntactic sugar for `public _____() {synchronized(this) {...}}`, so I *think* they get compiled the same – awksp May 22 '14 at 08:10
  • 1
    Interesting question, I guess it is decision of the compiler and therefore not generally answerable. I found this answer on Stackoverflow: http://stackoverflow.com/questions/417285/equivalent-code-for-instance-method-synchronization-in-java – Chrisport May 22 '14 at 08:13
  • I stand corrected. Didn't realize the first case would get optimized out. I wonder what would happen if there were code in the body of the method... – awksp May 22 '14 at 08:16
  • I tried out using different implementations for the methods of my example (but always both doing the same at a time) found the bytecode of synchronized(this) version is always 44 letters longer, similar to the stackoverflow answer above. I used javac 1.7.0_45 in Android Studio (0.5.8) – Chrisport May 22 '14 at 08:46
  • 1
    Using Java 1.8.0_05 on a `RingBuffer#isEmpty()` class, I got similar results, except the decompiled bytecode for the explicit `synchronized(this)` was nearly twice as long as the bytecode for the version with `synchronized` in the method signature. However, (didn't notice this earlier), `synchronized` remained in the signature of the method, which means that it's entirely possible that it's the JVM that does the hard work, and not the compiler... And I don't know nearly enough to figure out what bytecode/assembly the JVM executes... – awksp May 22 '14 at 08:56
0

enter image description here

Every object has a lock associated with it and all of its synchronized methods have to acquire its lock before enter the method. So, if any thread calls m1() or m2() on the object depicted in the diagram above, it has to acquire the lock on the object which contains m1() or m2() and not on itself.

Drona
  • 6,886
  • 1
  • 29
  • 35