10

As far as i know when there are multiple synchronized methods(both static and instance) in a class, java allows only one such method to run at a time. But what if a thread acquires lock on an object instance(or class), then enters a synchrozed method inside that object and then makes a call to another synchronized method of the same object. I mean to say:

Class AA  
{  
 ..  
 ..  
synchronized void X()  
{  
  Y();  
}

synchronized void Y()  
{  
 ..  
 ..  
}  

Is any thread execting the method X going to block forever? Since java wont allow to run both method X and Y at the same time?

Yeasir
  • 103
  • 1
  • 1
  • 5

3 Answers3

15

In Java, synchronized locks are re-entrant.

Or in other words if your thread already holds the lock on an object it doesn't have to wait on itself.

ratchet freak
  • 25,706
  • 2
  • 62
  • 97
  • Ok. That raises another question in my mind. Since _"Java allows only 1 of a set of synchronized methods to run at a time"_, and since the above code makes a call to another sync. method from inside a sync. method, will the thread holding a lock on this object will be allowed to run(get CPU share)? it seems to me it has created an infinite loop for itself. @ratchefreak – Yeasir Jun 10 '15 at 12:27
  • @Yeasir The thread will see that it already owns the lock on the object and just pass through the block after incrementing the `owned` counter. When leaving the method it will decrement the counter and release the lock if it hit 0. – ratchet freak Jun 10 '15 at 12:30
  • Thanks a lot man. Got it. Not have enough reputation to vote you up guys. @ratchetfreak – Yeasir Jun 10 '15 at 12:39
11

If you read carefully the documentation of synchronized you will find that it is explicitly stated that once a thread has acquired a lock, it is allowed to re-acquire it as many times as it pleases.

According to the Java Language Specification:

Section 8.4.3.6. "synchronized Methods" says that the synchronized keyword acquires a monitor. See: http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.3.6

Section "17.1 Synchronization" then says that A thread t may lock a particular monitor multiple times. See http://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.1

So, it is only other threads that have to wait if a thread has acquired a lock. The same thread may reacquire the lock without ever having to wait.

Mike Nakis
  • 32,003
  • 7
  • 76
  • 111
1

Java synchronisation uses a recursive lock for the instance of the synchronised method. It is as if each instance had a recursive lock, and @synchronized would lock that recursive lock (JVM uses a more clever method obviously). Therefore:

  1. Any number of threads can use @synchronized for different objects.
  2. One thread can use @synchronized for the same object multiple times.
  3. One thread can use @synchronized for any number of objects that are not @synchronized by any other thread.

For @synchronized class methods, a recursive lock for the class itself is used. Same rules apply as above, since classes are first class objects.

java allows only one such method to run at a time

Well, that's absolutely not true. First, 10 threads can call ten synchronized methods of ten different instances, and they can all run at the first time. Each synchronized method can in turn call other synchronized methods of other instances, and as long as they are not used with @synchronized methods, that will also work. And each @synchronized method can recursively call @synchronized methods of the same instance, as much as it likes.

The restriction is: No two threads can run @synchronized methods of the same instance simultaneously, or run @synchronized class methods of the same class simultaneously.

gnasher729
  • 42,090
  • 4
  • 59
  • 119
  • 1
    Well i guess the statement would be _*java allows only one synchronized method from the same object to run at a time*_. I get it when you say 10 threads can call ten synchronized methods of ten different instances and they can run simultaneously since each object has it's own copy of variables and methods. But does it also hold when there is a static sync. method or sync. methods that belong to a class object rather to an instance. I guess in this case 9 threads have to wait in queue to acquire a lock. @gnasher729 – Yeasir Jun 11 '15 at 03:43
  • The last point is what I wanted to know as well, thanks. – Rockstar5645 Feb 10 '21 at 20:35